Spring MVC4 Session Management - spring

I am developing a small spring project in which the login page has two type of users admin and staff. on login attempt i want to apply session using spring MVC4 and also wants to open jsp based on the user role(Admin or Staff).
the session has four/five fields like name,id,role,SessionId. i want these information to travel through the jsp pages. But i don't want to do this using url parameter passing.
I don't know how to do this because i am new in spring and this is my first project. Help me Please.
If someone can provide me the sample code and guide me on this then it would be very helpfull.
// Login.jsp code
var MobileNo=$('#mobno').val();
var StaffPwd=$('#pwd').val();
$.ajax
(
{
url: "http://localhost:8080/OnlineStore/kmsg/grocery/Login",
type: "POST",
data: {MobileNo: MobileNo,StaffPwd: StaffPwd},
success: function(data)
{
var vUserRole = data["UserRole"];
var vUserName = data["UserName"];
if(data==="")
{
alert("Login Failed");
}
else
{
if(vUserRole == "Admin")
{
alert("Login Success: " + vUserName);
window.location.href = "http://localhost:8080/OnlineStore/JspPages/City.jsp";
}
if(vUserRole == "CityAdmin")
{
alert("Login Success: " + vUserName);
window.location.href = "http://localhost:8080/OnlineStore/JspPages/Locality.jsp";
}
if(vUserRole == "Staff")
{
alert("Login Success: " + vUserName);
window.location.href = "http://localhost:8080/OnlineStore/JspPages/CustomerOrder.jsp";
}
}
},
error: function(e)
{
alert('Error:' +e)
}
}
);
// this is controller code
#RequestMapping("/Login")
public #ResponseBody UserServiceModel selectStaff(#RequestParam Map<String,String> requestParams) throws Exception
{
String MobileNo = requestParams.get("MobileNo");
String StaffPwd = requestParams.get("StaffPwd");
return staffAdapter.login(MobileNo, StaffPwd);
}
--------------

Just store your data in some serializable object. For e.g.:
public class SessionData implements Serializable {
private String name;
private String id;
private String role;
//etc..
}
then set this object as the session attribute when the user first logs in:
session.setAttribute("sessionData", new SessionData(name, id, role, etc...))
To access this object in a JSP page you can use: ${sessionScope['sessionData']}, to access a specific field:
${sessionScope['sessionData'].id}
${sessionScope['sessionData'].name}
${sessionScope['sessionData'].role}
To access these attributes in JavaScript files just define some page data in your JSP page, for e.g.:
<script type="text/javascript">
pageData = {
id: "${sessionScope['sessionData'].id}",
name: "${sessionScope['sessionData'].name}",
role: "${sessionScope['sessionData'].role}"
}
</script>
and in js file reference them via:
pageData.id
pageData.name
pageData.role
I can see that you trying to create roles based application. You are already using Spring MVC, any reason why not use Spring Security along with it? I would highly advice doing so as it will make your life much easier.

Related

SpringMVC change JSP with post

I'm trying to update the user's current JSP on a post request. I am using #Controller annotation right now (I've also tried RestController)
Controller:
#PostMapping(value = { "postHome" })
public ModelAndView postHome(#RequestBody String body, ModelAndView model) {
JSONObject jsonObject = new JSONObject(body);
String customerName = jsonObject.getString("customerName");
model.setViewName("feasibility");
model.addObject("customerName", customerName);
return model;
}
JavaScript:
function postCustomer() {
var custName = {
"customerName": document.getElementById("customerName").value
};
fetch(sendURL, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(custName)
});
}
It's posting to the server just fine (I've printed out the body), but nothing happens after that. No errors or anything. The JSP I am trying to update the client with is feasibility.jsp. I tried something earlier and it was trying to force my client to run a GET on localhost:8080/feasibility?customerName=Name but that's not what I was trying to do.
In the past I was able to just return "feasibility" as a String, but that doesn't work with this project (could be the versions I was using before).
Thanks!

Getting UserID from the Session In Extjs in some other js files of same App

In other way I want to access
(One functions Variable in another function in some other file of same application)
I'm trying to retrieve the UserID i got it from the session in some other .js files of a same application, How will I be able to do it?
This is my
session.js
function SessRequest() {
};
SessRequest.prototype.get = function (url, params, payload, session, cb, scope) {
var data = {};
if (payload) {
data.payload = payload;
}
if (url.indexOf('?') > -1) {
url = url + '&logonID=' + session.user.userID;
} else {
url = url + '?logonID=' + session.user.userID;
}
cb.call(scope, result.message, resp);
});
SessRequest.prototype.post = function (url, params, payload, session, cb, scope) {
params.logonID = session.user.userID;
rest.post(url, {data: params}).on('complete', function (data) {
cb.call(scope, 0, data);
});
};
Now This session.user.userID, I want this value to retrieve in a grid.js file of the same application, Can anyone help me in this ?
say me how to retrieve it and print it on console? If possible.
Please ask for any extra thing if My question is not clear?
thanks in advance
You could create a singleton class which holds the userid information.
Ext.define('APP.SessionInformation', {
singleton: true,
userid: null
});
When you retrived the information after successful login, you set it in the singleton.
APP.SessionInformation.userid = session.user.userID;
Now you are able to access it everywhere in you application by APP.SessionInformation.userid.

ASP.NET WEB API 2 OWIN Authentication unsuported grant_Type

Hi I am trying to set up OAuth bearrer token authentication in my ASP.NET Web API 2 project.
I have two project one will be the WEB API Project and the other a SPA project.
Here is what I have done so far:
I have created the OWIN Startup class:
[assembly: OwinStartup(typeof(CodeArt.WebApi.App_Start.Startup))]
namespace CodeArt.WebApi.App_Start
{
public class Startup
{
static Startup()
{
PublicClientId = "self";
UserManagerFactory = () => new UserManager<UserModel>(new UserStore<UserModel>());
OAuthOptions = new OAuthAuthorizationServerOptions {
TokenEndpointPath = new PathString("/Token"),
Provider = new OAuthAuthorizatonServer(PublicClientId, UserManagerFactory),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
}
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static Func<UserManager<UserModel>> UserManagerFactory { get; set; }
public static string PublicClientId { get; private set; }
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalBearer);
app.UseOAuthBearerTokens(OAuthOptions);
}
}
I have configured Web API to use only bearer token authentication:
private static void ConfigureBearerTokenAuthentication(HttpConfiguration config)
{
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(Startup.OAuthOptions.AuthenticationType));
}
I have configured WEB API to support CORS:
private static void ConfigureCrossOriginResourseSharing(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
}
I have created the OAuthAuthorizationServerProvider class.From this class I only managed to make my code call this method:
public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
if(context.ClientId == null)
{
context.Validated();
}
return Task.FromResult<object>(null);
}
The if condition inside of it always gets executed.
On my spa project I have the following:
This is my viewModel:
var vm = {
grant_type: "password",
userName: ko.observable(),
password: ko.observable()
};
When the login button gets clicked I call this function:
var http = {
post:function(url, data) {
return $.ajax({
url: url,
data: data,
type: 'POST',
contentType: 'application/json',
dataType: 'jsonp'
});
}
}
function loginClick() {
var model = ko.mapping.toJS(vm.loginModel);
var rez = $.param(model);
http.post("http://localhost:3439/Token", rez)
.done(function (data) {
console.log(data);
})
.fail(function(eror, stuff, otherstuff) {
console.log(eror);
console.log(stuff);
console.log(otherstuff);
});
}
My first attempt I have set the post calls dataType to json and I got this errors:
OPTIONS ...:3439/Token 400 (Bad Request) jquery.js:7845
OPTIONS ...:3439/Token No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin
'...:3304' is therefore not allowed access.
jquery.js:7845
XMLHttpRequest cannot load ...3439/Token. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin '...3304' is therefore not allowed
access.
The 3 dots represent http://localhost.
The second time arround I set it datatype to jsonp and I got back an error that stated unsupported "unsupported_grant_type".
Both calls make it to ValidateClientAuthentication that I mentioned above but they are both sent back as a failed request.
Now I am guessing that the problem is more related to how I am sending data instead of the grand_type because the SPA template in Visual Studion set's the grant type to grant_type: "password" like I did.
Also I have read that I have to serialize the data not send it in json in order for this to work here is the exact json serialized data that get's sent:
"grant_type=password&userName=aleczandru&password=happynewYear&moduleId=models%2FappPostModels%2FloginModel"
The model id property get's set to all my object in my SPA template by Durandal Framework.
Can anyone tell me what I am doing wrong I have been trying to figure this out for the last two days?
Add the following line of code to GrantResourceOwnerCredentials, which will add the header to the response.
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
for more information refer to:
web-api-2-0-cors-and-individual-account-identity
Like Robin Karlsson said, you should use:
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
in your Startup configuration.
And make sure it's the only cors statement (don't mix them) and the first statement in your Startup.

Forms validation in Nancy not working with AJAX login requests

I'm trying to implement an extremely simple spike using Nancy as an alternative to ASP.NET MVC.
It should take a username (no password) and provide meaningful error messages on the same login page without requiring a refresh. If login was successful, the response includes the URL to navigate to.
The POCO for the response looks like this:
public class LoginResponseModel
{
public bool IsSuccess { get; set; }
public string RedirectUrl { get; set; }
public string ErrorMessage { get; set; }
}
The JS handler for the login request:
$.ajax({
url: '/login',
type: "POST",
data: { UserName: username }
}).done(function (response) {
if (response.IsSuccess) {
showSuccess();
document.location.href = response.RedirectUrl;
return;
}
showError(response.ErrorMessage);
}).fail(function (msg) {
showError("Unable to process login request: " + msg.statusText);
});
The problem I'm having is with Nancy's Forms-based authentication. I've walked through half a dozen different tutorials which all more or less do the same thing, as well as gone over the Nancy authentication demos. The one thing they all have in common is that they rely on the LoginAndRedirect extension method. I don't want to return a redirect. I want to return a result of the login attempt and let the client handle the navigation.
The IUserMapper implementation I'm using:
public class UserMapper : IUserMapper
{
public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context)
{
// Don't care who at this point, just want ANY user...
return AuthenticatedUser {UserName = "admin"};
}
}
The relevant part of my LoginModule action:
var result = _userMapper.ValidateUser(input.AccessCode);
if (result.Guid != null) this.Login(UserMapper.GUID_ADMIN, expiry);
return Response.AsJson(result.Response);
but for subsequent requests Context.CurrentUser is always null.
If I add the following method to the Nancy.Demo.Authentication.Forms sample it reproduces the behaviour I'm seeing in my own project, leading me to believe LoginWithoutRedirect doesn't work how I expected.
Get["/login/{name}"] = x =>
{
Guid? userGuid = UserDatabase.ValidateUser(x.Name, "password");
this.LoginWithoutRedirect(userGuid.Value, DateTime.Now.AddYears(2));
return "Logged in as " + x.Name + " now <a href='~/secure'>see if it worked</a>";
};
The problem turns out to be that Context.CurrentUser with FormsAuthentication is dependent upon a cookie which isn't set if you don't return the NancyModule.Login() response.
var result = _userMapper.ValidateUser(input.AccessCode);
if (result.IsSuccess) {
this.LoginWithoutRedirect(result.Guid);
}
return Response.AsJson(result);
In this example, the LoginWithoutRedirect call returns a Response object with the cookie set. To handle this in an Ajax scenario I've had to add a AuthToken property to the LoginAjaxResponse class, then pass the cookie like so:
var result = _userMapper.ValidateUser(input.AccessCode);
var response = Response.AsJson(result);
if (result.IsSuccess) {
var authResult = this.LoginWithoutRedirect(result.Guid);
result.AuthToken = authResult.Cookies[0].Value;
}
return Response.AsJson(result);
On the client, the Ajax response handler changes to (assuming use of jQuery cookie plugin:
$.ajax({
url: '/login',
type: "POST",
data: { UserName: username }
}).done(function (response) {
if (response.IsSuccess) {
showSuccess();
$.cookie("_ncfa", response.AuthToken); // <-- the magic happens here
document.location.href = response.RedirectUrl;
return;
}
showError(response.ErrorMessage);
}).fail(function (msg) {
showError("Unable to process login request: " + msg.statusText);
});
The AuthToken is the GUID which has been encrypted and base64-encoded. Subsequent requests with this.RequiresAuthentication() enabled will first check for this auth token cookie.
If no "_ncfa" cookie is present,the UserMapper's GetUserFromIdentifier() is never called.
If the value in Context.Request.Cookies["_ncfa"] does not result in a valid GUID when base64-decoded and decrypted, GetUserFromIdentifier() is never called.
If GetUserFromIdentifier() isn't called, Context.CurrentUser is never set.
If you want the source for a working example it's on GitHub.
LoginAndRedirect is only one option, there are equivalent methods for not redirecting (LoginWithoutRedirect), or one that picks up on whether it's an AJAX request and handles it appropriately (Login). The same applies to logging out.
This is all covered, in detail, in the documentation.

Spring and Spring MVC 3.0 AJAX Intergration

Except for this article http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
I cannot find any good examples of the new AJAX related features in Spring 3.0. I am interested in how the web application build utilizing Spring MVC with Annotations can be integrated with the various AJAX frameworks, such as Dojo to provide rich user experience on the front end.
I think the article is pretty clear about the options. For example, based on it, I created the following method for verifying whether a username is in use or not:
/**
* #param username
* #return true if the username is free, false otherwise
*/
#RequestMapping("/account/checkUsername/{username}")
#ResponseBody
public boolean checkUsername(#PathVariable("username") String username) {
return userService.checkUsername(username);
}
And on the client side, using jQuery:
$("#username").live("blur", function() {
$.getJSON("account/checkUsername/" + $("#username").val(),
function(response) {
// do something with JSON response
}
);
});
var xhrArgs = {
url: "account/checkUsername/" +dojo.byId('').value,
handleAs: 'json',
load: function(response) { response(data);}
};
dojo.xhrGet(xhrArgs);
function YourJavaScriptFunctionHere(){
byObj1.loading()
setGridData(gridNon,[])
var url='dispatch=getMETHOD&PARAMETER='+Math.random()*9999;
var ajax=new ajaxObject('YOUR CONTROLLER MAPPING');
ajax.callback=function(responseText, responseStatus, responseXML) {
if (responseStatus == 200) {
var myArray = eval("("+responseText+")");
if(myArray["error"]){
alert(myArray["error"]);
}else{
setGridData(byObj1,myArray)
}
byObj1.loadingCompleted();
}
}
ajax.update(url,'POST');
}

Resources