Spring MVC duplicate requests ignoring checks in the service layer - spring-mvc

I am using the spring-boot mvc in my project and there is a strange issue that I am facing.
I have this method in my service layer
#Autowired
UserRepository userRepository;
public void registerUser(User user) {
User existingUser = userRepository.findByUsername(user.getUsername());
if (existingUser != null) {
throw new UserException("Sorry! This username is already taken");
}
// other validations
userRepository.save(user);
}
Surprisingly , there are entries into the database that have the same username. This happens when the the front-end POSTs multiple requests for the same form content.
I have two questions:
1 .Is there an option for me to stop this at the back-end (Java)in addtion to asking the front-end to disable the submit button after click?
Will it be a security risk if it is handled only on the front-end?

Related

Need advice of where to put custom user authorization in ASP.NET Core

I need advice of where to put custom user authorization code in ASP.NET Core. I am somewhat a ASP.NET Framework developer and normally I will add code to Global.asax as a session_onstart event to look up a SQL table where users profile are stored that is used to determine what they can view in the rest of the application. With Global.asax this is only cause once per user session, so what I would like to do is the same kind of approach in ASP.NET Core which I am kind of new to but need advice where that check should be done
I would like to do is the same kind of approach in ASP.NET Core which
I am kind of new to but need advice where that check should be done
Well, based on your description, in asp.net core you can achieve that in many ways. For instances, you could set in following places:
program.cs/startup.cs files
Using Middleware file
Using Action Filter
Let's, consider below example using action filter
Role and permissison:
First we are defining the role and the permission.
public enum Role
{
User,
Admin,
SuperAdmin
}
public enum Permission
{
Read,
Create,
Update,
Delete
}
Authorization On Action Filter:
public class AuthorizeActionFilter : IAuthorizationFilter
{
private readonly Role _role;
private readonly Permission _permission;
public AuthorizeActionFilter(Role item, Permission action)
{
_role = item;
_permission = action;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var isAuthorized = context.HttpContext.User.Claims.Any(c => c.Type == _role.ToString() && c.Value == _permission.ToString());
if (!isAuthorized)
{
context.Result = new ForbidResult();
}
}
}
Note: Check your user claim from the HttpContext if that containts either Admin or Read authorization.
Controller:
[Authorize(Role.User, Permission.Read)]
public IActionResult MemberList()
{
var memberList = _context.Members.ToList();
return View(memberList);
}
Output:
You even can implement that using Middleware. Asp.net 6 now providing couple of other mechanism now a days, you could have a look below official implementations as well.
Role-based authorization
Claims-based authorization
Policy-based authorization
Custom Action Filter

Spring Security: Custom Authentication Provider

I have developed an application with spring mvc for high user traffic. Suppose there is least 20,000 concurrent user. I have implemented spring security custom authentication provider in two ways.
1st one is :
#Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
CustomUser user = _userDetailService.loadUserByUsername(username);
if (user == null || !user.getUsername().equalsIgnoreCase(username)) {
throw new BadCredentialsException("Username not found.");
}
if (!BCrypt.checkpw(password, user.getPassword())) {
throw new BadCredentialsException("Wrong password.");
}
Collection < ? extends GrantedAuthority > authorities = user.getAuthorities();
return new UsernamePasswordAuthenticationToken(user, password, authorities);
}
2nd one is:
#Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
try {
Authentication auth = super.authenticate(authentication);
//if reach here, means login success, else an exception will be thrown
//reset the user_attempts
return auth;
} catch (BadCredentialsException e) {
//invalid login, update to user_attempts
throw e;
}
}
Now my question is whice implementation will give me the faster output?
As already pointed out by Afridi, your 1st version is exactly what DaoAuthenticationProvider is supposed to do. I would strongly discourage from re-implementing its functionality, since you might for example introduce new security relevant errors.
If you really need a custom authentication method, there is no way around a custom authentication method of course. In order to measure the performance of this implementation in general or versus the standard implementation, you should simply define a test scenario (e.g. 20000 dummy authentications as homlis83 suggested) and run the program in a profiler. This will how you exactly how much time is spent in you authentication method and even which part takes the most time.
I think the most popular Java profiler is VisualVM and depending on your IDE there might be a plugin that further simplifies its use. There are also a lot of tutorials for Java profiling out there, but this is definitvely the way to go for you to get reliable data for the performance.

How to Customize ASP.NET Web API AuthorizeAttribute for Unusual Requirements

I am inheriting from System.Web.Http.AuthorizeAttribute to create a custom authorization/authentication routine to meet some unusual requirements for a web application developed using ASP.NET MVC 4. This adds security to the Web API used for Ajax calls from the web client. The requirements are:
The user must logon each time they perform a transaction to verify
someone else has not walked up to the workstation after someone has
logged on and walked away.
Roles cannot be assigned to the web service methods at program time.
They must be assigned at run time so that an administrator can
configure this. This information is stored in the system database.
The web client is a single page application (SPA) so the typical forms authentication does not work so well, but I am trying reuse as much of the ASP.NET security framework as I can to meet the requirements. The customized AuthorizeAttribute works great for requirement 2 on determining what roles are associated with a web service method. I accept three parameters, application name, resource name and operation to determine which roles are associated with a method.
public class DoThisController : ApiController
{
[Authorize(Application = "MyApp", Resource = "DoThis", Operation = "read")]
public string GetData()
{
return "We did this.";
}
}
I override the OnAuthorization method to get the roles and authenticate the user. Since the user has to be authenticated for each transaction I reduce the back and forth chatter by performing authentication and authorization in the same step. I get the users credentials from the web client by using basic authentication which passes the encrypted credentials in the HTTP header. So my OnAuthorization method looks like this:
public override void OnAuthorization(HttpActionContext actionContext)
{
string username;
string password;
if (GetUserNameAndPassword(actionContext, out username, out password))
{
if (Membership.ValidateUser(username, password))
{
FormsAuthentication.SetAuthCookie(username, false);
base.Roles = GetResourceOperationRoles();
}
else
{
FormsAuthentication.SignOut();
base.Roles = "";
}
}
else
{
FormsAuthentication.SignOut();
base.Roles = "";
}
base.OnAuthorization(actionContext);
}
GetUserNameAndPassword retrieves the credentials from the HTTP header. I then use the Membership.ValidateUser to validate the credentials. I have a custom membership provider and role provider plugged in to hit a custom database. If the user is authenticated I then retrieve the roles for the resource and operation. From there I use the base OnAuthorization to complete the authorization process. Here is where it breaks down.
If the user is authenticated I use the standard forms authentication methods to log the user in (FormsAuthentication.SetAuthCookie) and if they fail I log them out (FormsAuthentication.SignOut). But the problem seems to be that base OnAuthorization class does not have access to Principal that is updated so that IsAuthenticated is set to the correct value. It is always one step behind. And my guess is that it is using some cached value that does not get updated until there is a round trip to the web client.
So all of this leads up to my specific question which is, is there another way to set IsAuthenticated to the correct value for the current Principal without using cookies? It seems to me that cookies do not really apply in this specific scenario where I have to authenticate every time. The reason I know IsAuthenticated is not set to the correct value is I also override the HandleUnauthorizedRequest method to this:
protected override void HandleUnauthorizedRequest(HttpActionContext filterContext)
{
if (((System.Web.HttpContext.Current.User).Identity).IsAuthenticated)
{
filterContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
This allows me to return a status code of Forbidden to the web client if the failure was because of authorization instead of authentication and it can respond accordingly.
So what is the proper way to set IsAuthenticated for the current Principle in this scenario?
The best solution for my scenario appears to be bypass the base OnAuthorization completely. Since I have to authenticate each time cookies and caching the principle are not of much use. So here is the solution I came up with:
public override void OnAuthorization(HttpActionContext actionContext)
{
string username;
string password;
if (GetUserNameAndPassword(actionContext, out username, out password))
{
if (Membership.ValidateUser(username, password))
{
if (!isUserAuthorized(username))
actionContext.Response =
new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
}
else
{
actionContext.Response =
new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
}
else
{
actionContext.Response =
new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
}
}
I developed my own method for validating the roles called isUserAuthorized and I am not using the base OnAuthorization any more since it checks the current Principle to see if it isAuthenticated. IsAuthenticated only allows gets so I am not sure how else to set it, and I do not seem to need the current Principle. Tested this out and it works fine.
Still interested if anyone has a better solution or can see any issues with this this one.
To add to the already accepted answer: Checking current sourcecode (aspnetwebstack.codeplex.com) for System.Web.Http.AuthorizeAttribute, it looks like the documentation is out of date. Base OnAuthorization() just calls/checks private static SkipAuthorization() (which just checks if AllowAnonymousAttribute is used in context to bypass the rest of the authentication check). Then, if not skipped, OnAuthorization() calls public IsAuthorized() and if that call fails, it then calls protected virtual HandleUnauthorizedRequest(). And that's all it does...
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
if (SkipAuthorization(actionContext))
{
return;
}
if (!IsAuthorized(actionContext))
{
HandleUnauthorizedRequest(actionContext);
}
}
Looking inside IsAuthorized(), that's where Principle is checked against roles and users. So, overriding IsAuthorized() with what you have above instead of OnAuthorization() would be the way to go. Then again, you'd still have to probably override either OnAuthorization() or HandleUnauthorizedRequest() anyway to decide when to return a 401 vs a 403 response.
To add to the absolutely correct answer by Kevin, I'd like to say that I may slightly modify it to leverage the existing .NET framework path for the response object to ensure downstream code in the framework (or other consumers) is not adversely affected by some weird idiosyncrasy that can't be predicted.
Specifically this means using this code:
actionContext.Response = actionContext.ControllerContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, REQUEST_NOT_AUTHORIZED);
rather than:
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
Where REQUEST_NOT_AUTHORIZED is:
private const string REQUEST_NOT_AUTHORIZED = "Authorization has been denied for this request.";
I pulled that string from the SRResources.RequestNotAuthorized definition in the .NET framework.
Great answer Kevin! I implemented mine the very same way because executing OnAuthorization in the base class made no sense because I was verifying an HTTP Header that was custom to our application and didn't actually want to check the Principal at all because there wasn't one.

Building ASP.Net custom authorization against database without MVC

this is my first request, so don´t be too hard. :)
We are building an Sharepoint 2010 - Application, which consists of some Sharepoint Web Parts and many ASP.Net-Sites. Therefore we are limited to use ASP.Net without MVC. This decision is made and can´t be refused.
We are using Windows Authentification with Impersonation. The Users are stored in an application database. Along with the users there are roles which have rights to specific objects and specific actions. all these informations are stored in the custom database.
The database has a data access layer (EF 4.0). Because Sharepoint is limited to .NET Framework 3.5, the business logic consists of a WCF Data Service which is using the DAL and business logic libary which accessing the WCF Data Service to grab the required information.
The ASP.Net-Pages and Sharepoint Web Parts are directly accessing the business logic.
What i now need is some kind of a Manager-Class which is checking the user against the database to authorize him to access the specific objects. I dont want to do it programmaticly. I want to use annotations to specify if a method from the business layer can be called or not. Furthermore i want to hide some things in the ASP.Net Sites without an programmaticly if-clause.
Can someone give me a hint to achieve this? Is there a way do customize some part of the standard framework to realize it?
The user and his roles and rights i want to store in a session. Is this a good way? the application is accessible only in local network.
Welcome to stackoverflow! A few thoughts on this -
You may be better suited to ask these questions at the cousin site http://sharepoint.stackexchange.com.
This depends on your web farm architecture. If your web front end and data sources are on the same server, then it should be simple to use windows authentication to determine the current user. However, if your web front ends and data sources are on separate servers, then you've reached a limitation due to the "double hop" scenario, where the user's credentials cannot be shared to the server behind the sharepoint server - so to speak.
To work around, investigate using Kerberos authentication in your SharePoint environment, which allows SharePoint to track user credentials throughout the farm - http://blogs.technet.com/b/tothesharepoint/archive/2010/07/22/whitepaper-configuring-kerberos-authentication-for-sharepoint-2010-and-sql-server-2008-r2-products.aspx
Yet another alternative, don't use SharePoint as your application host. Create your web application and deploy it as its own website (http://mysupercoolsite.organization.com), and in SharePoint create a new "web part page", with a "full page vertical" layout. Then, add a "Page Viewer" web part to the page, supplying the url to mysupercoolsite.organization.com. This way, SharePoint is a "portal" to this application for your users, but all authentication, authorization, and structure are based on the application itself, and not at all in SharePoint.
We have stayed at sharepoint as application host.
I´ve implemented a Custom UserControl which implements all the security questions.
public partial class FMD_RoleEnabledControl : System.Web.UI.UserControl
{
public string EnabledRoles { get; set; }
public bool HasDataBinding { get; set; }
public string CurrentUserName
{
get { return Page.User.Identity.Name; }
}
protected override void OnPreRender(EventArgs e)
{
if (!HasDataBinding)
Visible = EnabledRoles.Split(',').Any(rolle => new FMDRoleProvider().IsUserInRole(CurrentUserName, rolle));
base.OnPreRender(e);
}
protected override void OnLoad(EventArgs e)
{
if(HasDataBinding)
Visible = EnabledRoles.Split(',').Any(rolle => new FMDRoleProvider().IsUserInRole(CurrentUserName, rolle));
base.OnLoad(e);
}
}
Custom-RoleProvider
public class FMDRoleProvider : RoleProvider
{
public const string SEPERATOR = ",";
...
public override string[] GetRolesForUser(string username)
{
if (username == null || username == "")
throw new ProviderException("Kein User-Name übergeben"); //TODO
string tmpRollen = "";
RechteManager rm = new RechteManager();
var rollen = rm.GetUserRollen(username);
foreach (var rolle in rollen)
{
tmpRollen += rolle.ROL_Name + SEPERATOR;
}
if (tmpRollen.Length > 0)
{
//Letzten seperator entfernen
tmpRollen = tmpRollen.Substring(0, tmpRollen.Length - 1);
return tmpRollen.Split(',');
}
return new string[0];
}
...
public override bool IsUserInRole(string userName, string roleName)
{
if (userName == null || userName == "")
throw new ProviderException("User name cannot be empty or null."); //TODO
if (roleName == null || roleName == "")
throw new ProviderException("Role name cannot be empty or null."); //TODO
RechteManager rm = new RechteManager();
return rm.IsUserInRolle(userName, roleName);
}
}
Usage
public partial class CustomControl: FMD_RoleEnabledControl
<custom:CustomControl ID="custom" runat="server" EnabledRoles="Admin" HasDataBinding="True" />
Its only the first approach to check against roles, but it works very well. As a second target i am going to implement extra security stuff like checking against speficic actions. Also the RoleProvider has to be registered in web.config. But time is short ;)

What is the correct way to implement login with redirect using JSF 2.0?

Part of my site should be accessible only to authorized users. Let's assume user would enter page a.html which belongs to the authorized-only part.
If I was to use servlets/JSP I could write a filter that checked whether user is logged in and if not - redirected him to login page. After a successful login user would be redirected to the page he wanted to reach initially, in this case a.html. (Page address could be stored in request).
What is a proper way to implement such scenario in JSF 2.0?
Just do it the same way, with a Filter. It's good to know that JSF session scoped managed beans are under the covers stored as a HttpSession attribute with the managed bean name as key.
Assuming that you've a managed bean like this:
#ManagedBean
#SessionScoped
public class UserManager {
private User user;
// ...
public boolean isLoggedIn() {
return (user != null);
}
}
Then you can check it in Filter#doFilter() as follows:
UserManager userManager = (UserManager) ((HttpServletRequest) request).getSession().getAttribute("userManager");
if (userManager != null && userManager.isLoggedIn()) {
chain.doFilter(request, response);
} else {
((HttpServletResponse) response).sendRedirect("login.xhtml");
}

Resources