Spring login need custom msg on screen - spring-mvc

I want to display custom message which will be fetched from database when user try to login on login page. This message can be changed by administrator. So always need to be fetched from database.
We are using acegi spring.
Do anybody know how to do this?
Jaydeep.

set your login page to be served from a controller, then you can set a modelattribute with your custom message and show it on the login screen
e.g.
#ModelAttribute("customMessage")
public String populateCustomeMessage() {
String msg // Code to get message from db and set it into a string
return msg;
}
#RequestMapping(value = "/login.html", method = RequestMethod.GET)
public String handleRequest() {
return "login";
}

Following link somewhat discusses on the topic you need (but not fetching from database)
how to display custom error message in jsp for spring security auth exception

Related

spring MVC change displayed URL in controller

I have an issue, let me introdues it:
I have a form which registers new users, the form then send information an address: ".../add-user.htm". In controller i have mapping for the address like this:
#RequestMapping(value = "add-user", method = RequestMethod.POST)
public ModelAndView addUser(#ModelAttribute("user") User user) {
ModelAndView modelAndView;
List<String> errors = userService.userRegisterErrors(user);
if(errors.size() == 0) {
//some code here...
modelAndView = new ModelAndView("index");
List<String> info = new ArrayList<String>();
info.add("Registration has been successful");
info.add("Verification e-mail has been sent to Your e-mail address");
modelAndView.addObject("info", info);
} else {
//some code here..
modelAndView = new ModelAndView("user/register");
modelAndView.addObject("user", user);
modelAndView.addObject("errors", errors);
}
return modelAndView;
}
At index page I'd like to show the info/error messages depends on if the registration was successful or not.
Let's assume the registration was correct for example. Then I'd like to see the index page with information for registration which works fine. The problem is with URL displayed at index page - it's not /index.htm as I wish, but it's /add-user.htm like controller defines. That's wrong because if i press "f5" button then it forces me to "re-register" the user.
I tried to use this method before returning modelAndView: modelAndView.setViewName("index.htm"); but nothing happened. I can redirect to index page in controller, but then I would lost all objects in modelAndView so no information would not be displayed. Another idea I had was to use a flag for info and error but it would be very complicated. Do you have a solution? thanks.
RedirectAttributes could suit your needs, especially the method addFlashAttribute. See the class' javadoc, it explains the purpose of using these attributes.

How to return a custom view OR a JSON when the Authorization fail, instead of showing a username and password dialog

I am working on an asp.net mvc 4 web application , and i wrote the following custom authorization class:-
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CheckUserPermissionsAttribute : AuthorizeAttribute
{
public string Model { get; set; }
public string Action { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.Request.IsAuthenticated)
return false;
//code goes here
if (!repository.can(ADusername, Model, value)) // implement this method based on your tables and logic
{
return false;
//base.HandleUnauthorizedRequest(filterContext);
}
return true;
// base.OnAuthorization(filterContext);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
var viewResult = new JsonResult();
viewResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
viewResult.Data = (new { IsSuccess = "Unauthorized", description = "Sorry, you do not have the required permission to perform this action." });
filterContext.Result = viewResult;
}
else
{
var viewResult = new ViewResult();
viewResult.ViewName = "~/Views/Errors/_Unauthorized.cshtml";
filterContext.Result = viewResult;
}
base.HandleUnauthorizedRequest(filterContext);
}
}
}
but the only problem i am facing now is that if the authorization fail then the user will be prompted to enter username and password, although i have override the HandleUnauthorizedRequest to return a view or JSON based on if the request is AJAX or not. so can you advice why the user is being prompted to enter his username and password when the authorization fail, instead of receiving the _unauthorized view or the JSON containing an error message
but the only problem i am facing now is that if the authorization fail
then the user will be prompted to enter username and password,
although i have override the HandleUnauthorizedRequest to return a
view or JSON based on if the request is AJAX or not.
That's because you are absolutely always hitting the following line in your HandleUnauthorizedRequest method:
base.HandleUnauthorizedRequest(filterContext);
You know what this line do? It calls the base method. You know what the base method do? It returns 401 status code. You know what happens when 401 status response code is returned in an ASP.NET application in which you are using Forms Authentication? You get the login page.
So yeah, if you are using AJAX or something and intend to be returning some JSON or something make sure that the base stuff is never called. By the way in your else condition you seem to be attempting to render some ~/Views/Errors/_Unauthorized.cshtml view which obviously is useless once again because you are also calling the base method which will simply redirect to the login page.
I think that at this stage of my answer you already know what to do: get rid of this last line of your HandleUnauthorizedRequest method in which you are throwing all your efforts into the trash by calling the base method.
And if you want to do things properly and return 401 status code and not get the login page but instead return some custom JSON you could use the SuppressFormsAuthenticationRedirect property on the Response object. And if you are using some legacy version of the .NET framework which doesn't have this property you might find the following blog post useful in which Phil Haack explains how to handle this case.

ASP.NET Web API how to authenticate user

I'm trying to create a simple user authentication function but I just can't get it to work.
Here is the code I'm working on:
public class LoginController : ApiController
{
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
public bool Login(string token)
{
//Check token
if (.....)
{
//Authenticate user
var identity = new GenericIdentity("Test user");
SetPrincipal(new GenericPrincipal(identity, new string[]{"Test role"}));
}
}
[Authorize]
public string TestFun()
{
return "Hello " + User.Identity.Name;
}
}
So, if I try to call method TestFun() first, it returns error code 401 like it should.
However when I call method Login() it should somehow save user credentials, but this is where I get lost, I just can't get it to work.
TestFun() always returns error code 401 even if I call Login() first.
If I try to put return "Hello " + User.Identity.Name; in the Login() function it returns correct username, but in the TestFun() the user is not available.
I've even tried using Sessions and FormsAuthentication but I just can't get it to work, even on this really simple example.
Can someone please tell me what am I missing?
Thanks!
The Login method sets the principal for current request only. Just after the request completes, the principal context is wiped out so that the server can handle other requests for other users. When a new request comes, eons later from the server perspective, the principal context no longer exists and if nothing restores it, the request is unauthenticated.
To fix this you have to return something from your login method to the client. Not only bool but rather - an authentication token. Something the client could use to authenticate further requests.
It could be anything. Forms cookie would be fine as long as the client remembers to append it to further requests. Another common practice is to have a custom authentication token returned to the client and then appended by the client in a custom authentication header. And as forms cookies are handled by the Forms Authentication module, custom headers would need a custom mvc authentication filter or custom asp.net authentication module so that the token is readed, the identity is extracted and restored just before the request is about to execute.
If you don't like to bake your own token infrastructure, I would also recommend OAuth2 tokens. There is a great book that contains easy to follow examples on this and other possible authentication methods:
http://www.amazon.com/Pro-ASP-NET-Web-API-Security/dp/1430257822/ref=sr_1_1?ie=UTF8&sr=8-1&keywords=web+api+security
I just got the same issue, yes, I agreed we need to save that principal into somewhere (cookie, session) for other action to use, so, in SetPrincipal function I added
HttpContext.Current.Session["user"] = HttpContext.Current.User;
Now, the issue is how to get it back for other action, the idea popups in my mind is to extend AuthorizeAttribute and override IsAuthrized function, it will read the session first and if it found the session, it will return true, otherwise it will return false.
namespace BinZ
{
public class MyAuthorizeAttribute:AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext) {
HttpContext.Current.User = HttpContext.Current.Session["user"] as IPrincipal;
return HttpContext.Current.User != null;
}
}
}
Please remember to replace [Authorize] to [MyAuthorizeAttribute] in WebApi controller.
It works for me very well.
Cheers

Reset Password in ASP.NET MVC

I am implementing my own reset password in ASP.NET. In reset password, first I create a random string and mail it to user email.For the link in email like http://xyz.com/account/forgot?random=xxxx&userid=xx.I created a httpget type action forgot which show return a view with input tags for passwords if randomid and userid are validated.
But in httppost type of forgot, I have confusion about the parameters.
I have forgotModel having 2 properties password and confirmpassword.If I just pass forgotmodel to httppost action, then I cannot query user from database.I think I should pass randomId as parameter.But, I am getting how to grab randomID from url of httpget action (If I do so, is it safe?)?
Please guide me, I got stuck..
Thanks in advance
Are you using like Html.BeginForm("action","controller"), If so then you will loose querystring parameters. Since HttpGet and HttpPost methods of ForGotPassword(..) have same action name, You can just use Html.BeginForm().
So, the form will post data to the page url and you will get querystring along with it.
in your http post method you can define like,
[HttpPost]
public ActionResult ForGot(ForgotModel model, string random,strung userid)
{
:
:
}
If you do not want to follow the above approach, then in httpget method write to ViewBag/ViewData and put them as hidden field in view. Then you can receive them as input to Method.
[HttpGet]
public ActionResult ForGot(string random,strung userid)
{
ViewBag.Random =random;
Viewbag.Userid =userid;
:
:
}
[HttpPost]
public ActionResult ForGot(ForgotModel model, string random,strung userid)
{
:
:
}
and , in view
#Html.BeginForm("ForGot","Account"){
:
#Html.Hidden(ViewBag.Random)
#Html.Hidden(ViewBag.Userid)
:
}

Using FormsAuthentication on webMethod

I have a page that has a comment section. This section communicates to a WebMethod in order to insert a new comment.
[WebMethod]
public static bool insertComment(string commentString)
{
//userName validation here
string userName = (FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name);
return new CommentClass().InsertComment(commentString, userName);
}
The problem is: "An object reference is required for the non-static field".
I know I could send the information from a hidden field, or a div, however, that information field may be changed easily.
So which way could be used to know which user is posting, in server side?
thanks a lot!
Request object is an instance that lives in Page, so you need a reference to access this object in a static context. You can use HttpContext.Current.Request for accessing the Request in this context.
[WebMethod]
public static bool insertComment(string commentString)
{
//userName validation here
string userName =
(FormsAuthentication.Decrypt(
HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name);
return new CommentClass().InsertComment(commentString, userName);
}

Resources