Spring MVC Security Token based Authentication - spring-mvc

Can anyone please help me in this.
I have been assigned to secure an existing web application.
Issue:
when a user already logs into the application (that means the session is active), at that time an attacker can guess the input fields and save url and create a similar page and send a hyper link. If the user clicks on that link, it will not go through javascript, rather it will hit the spring controller. Since the session is active, it will save the attackers data into the database.
Here is what we are using now.
1) Spring Security
<http auto-config="true">
<intercept-url pattern="/**" access="ROLE_ADMIN, ROLE_HR" />
<custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</http>
<beans:bean id="siteminderFilter" class="com.mywbsite.security.UserFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="continueFilterChainOnUnsuccessfulAuthentication" value="false"/>
</beans:bean>
This method is called when user logs into the application first time
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
String userId = request.getHeader("uid");
logger.info("<<<<<<<<<<<<<<<<<<<<<userId>>>>>>>>>>>>>>>>>>>>>>> : "+userId);
return userId;
}
This method is called when user does anything which calls any controller/java
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println(request.getParameter(BaseConstants.DV_USER_SESSION_IDENTIFIER));
logger.info(request.getParameter(BaseConstants.DV_USER_SESSION_IDENTIFIER));
logger.info("Existing the UserFilter.doFilter method...");
}
Solution:
In controller/filter I have to identify if the request is coming from my application or from anywhere else.
Here is what I am thinking to implement.
Create a random token inside getPreAuthenticatedPrincipal() method and store that in session.
Get the variable from session and put in a hidden variable in jsp
When user does any action, pass the hidden variable with value and pass to controller as request parameter.
In Controller/Filter get the random value from session and get the hidden value from request parameter. Now compare. If it matches, then do normal operation, else throw error page.
Now my concern is if I implement the above solution, I have to write hidden variable code in every jsp and pass to controller in each request and request parameter.
Can you please help me how to make it easy. Thanks in advance

I resolved the above issue by using Spring CSRF. I faced an issue while implementing CSRF. The issue was CSRF was creating 2 tokens. It took long time (at least 1 day) to find the root cause. The root cases was I was trying to get the csrf token value in my Fiter and print it using below code. So once I wrtie the request.getAttribute("_csrf"), it creats a new token. So I just delted the below lines from my csrf and just did what it was described in above spring csrf link. It worked
// CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
// System.out.println(">>>>>>>>>>UserFilter.getPreAuthenticatedPrincipal() CSRF Token: " + token.getToken());

Related

Find out which federated partner issued token to WIF

I have an application that uses the Windows Identity Foundation to enable federated single-sign-on from multiple partners (let's call them Org1, Org2, Org3, etc). My WIF configuration, therefore, contains thumbprints of all the partners' certificates - the config looks like this (irrelevant parts omitted for brevity):
<system.identityModel>
<identityConfiguration>
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry">
<trustedIssuers>
<add name="Org1" thumbprint="...certificate1..." />
<add name="Org2" thumbprint="...certificate2..." />
<add name="Org3" thumbprint="...certificate3..." />
</trustedIssuers>
</issuerNameRegistry>
</identityConfiguration>
However, I don't understand how to determine which of the certificates was actually used when an incoming token was validated. That is, how do I know whether it was Org1, Org2 or Org3 that has sent me the token? I.e., in the following code:
var authModule = FederatedAuthentication.WSFederationAuthenticationModule;
var request = new HttpRequestWrapper(Request);
if (authModule.CanReadSignInResponse(request, true))
{
var principal = Thread.CurrentPrincipal;
var message = authModule.GetSignInResponseMessage(request);
var token = authModule.GetSecurityToken(request) as SamlSecurityToken;
//???
}
... How can I use the principal/message/token variables (or perhaps some other method entirely) to determine whether it was Org1, Org2 or Org3 that has sent me the token? I know about token.Assertion.Issuer, but this seems to come straight from the token, so it seems like e.g. Org1 can issue a token listing Org2 as the issuer, thus resulting in an impersonation attack. Is there a way to identify the issuing organization securely, based on which certificate was used for token validation?
I managed to find 2 solutions:
METHOD 1:
Create a custom IssuerNameRegistry that derives from System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, and set it as your name registry (e.g. <issuerNameRegistry type="MyNamespace.MyConfigurationBasedIssuerNameRegistry, My.Assembly.Name">).
In your custom registry, override the GetIssuerName overload that takes both a token and a string (which is the token's issuer according to the token itself).
In this override, call the base GetIssuerName method, and you will get back the name property of the <add thumbprint="..." name="..."> statement for the certificate that was actually used to verify the token signature.
At this point, you have all the information you need (who the token claims to be, and who it is actually from). Compare the two, and return null if the token is impersonated (this will cause WIF to reject the token), or return what you got from the base method otherwise.
If your name property in <add> statements is always the intended token issuer URL, then all this becomes very easy:
class ValidatingConfigurationBasedIssuerNameRegistry : ConfigurationBasedIssuerNameRegistry
{
public override string GetIssuerName(SecurityToken securityToken, string requestedIssuerName)
{
var configuredName = base.GetIssuerName(securityToken, requestedIssuerName);
return (configuredName == requestedIssuerName) ? configuredName : null;
}
}
METHOD 2:
As stated in the answers here, you can get to the Claims on Thread.CurrentPrincipal as ClaimsPrincipal, and each Claim has an Issuer property. It turns out that this property will always be set to the name property in the <add thumbprint="..." name="..."> statement for the certificate that was actually used to verify the token signature.
This is a bit inconvenient - if you're processing a WS-Federation sign-in response, there's no way of knowing where this particular response's token came from - you're looking at the current Identity where the claims could potentially come from multiple sources. But I think in most realistic scenarios this should be sufficient.

Forwarding A Request From One Controller Function To Another in Spring 2.5.2

I have two classes called :
List of users page
Edit user page
Iam using SimpleFormController in spring 2.5.2 version.
In this bellow method I want to edit the users information. After successfully submitting this form I need to forward the page to list of users page.
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse
response, Object command, BindException errors){
}
I configured this edit page in dispatcher-servlet as bellow:
<bean name="edituser" class="com.users.EditUserController"/>
How can I forward the page from onsubmit method.

HttpServletResponse: Keep, Save or Persist the response for later use...?

I am using Spring to create my webapp. I have a scenario like:
An ExternalService sends a GET request to my Controller that has a mapping /DoOperation with some user info as param. I get the param check the user if he is logged into my system or not if NOT i send him to OpenId verification with returnUrl, which is in same webapp say /Authenticated.
The ExternalService does not provide a returnUrl (Not related to OpenId returnUrl) and forces to respond the same request it made at /DoOperation.
Now, How could I keep the very HttpServletResponse (if there is a way, apparently there is not) so that I can write a response once I have gone somewhere else e.g. at OpenID page to verify user and then /Authenticate in this case... so that ExternalService could read it.
Could Servlet Filter help here?

how to retrieve Login Form password in Custom UserDetailsService

I have a Custom User class that extends the User(Spring Security's) class and Custome UserDetailsService class. This service queries the database using Hibernate service method to fetch user details. If there is no records found in the database for that userId, instead of throwing a UsernamNotFoundException, I want to create a dummy Custom user object and pass the authentication with read-only attributes. But I can't get it working because, I am not sure how to retrieve the password value entered by user on the login page. I need to pass it to the custom user constructor to get it authenticated properly..
So, to sum it up, is there anyway to retrieve password entered by the user on login page inside the loadUserByUserName() method? Thanks in advance
I am doing something in a similar vein a current project. I have just started getting into Spring Security over the past 2 weeks, but I've really dug into it during that time (attached source, went through it in the debugger).
I have a Custom User class that extends org.springframework.security.core.userdetails.User and a custom class that implements org.springframework.security.core.userdetails.UserDetailsService interface.
As you know, the signature of the loadUserByUsername method in UserDetailsService interface specifies that a class implementing UserDetails interface is going to be returned.
Spring Security is going to take the class that implements UserDetails and check the username and password provided by login form / basic authentication / digest authentication / (whatever authentication scheme you selected) against the Username and Password in UserDetails.
I have not found a way that you can get at the credentials provided by the end user via authentication scheme. If you want, I could try looking into it when I'm back at work tomorrow (I'm at home and writing this from memory.
I am running Spring 3.0.6 RELEASE and Spring Security 3.0.6 RELEASE.
I ran the code in my debugger. You will not be able to get at the Authentication object from the custom UserDetailsService.
However, I believe you may be able to create your own AuthenticationProvider that gets at it: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/core-services.html
Please reference this code snippet from Spring Security's org.springframework.security.authentication.ProviderManager, which loops over the AuthenticationProvider(s):
for (AuthenticationProvider provider : getProviders()) {
if (!provider.supports(toTest)) {
continue;
}
logger.debug("Authentication attempt using " + provider.getClass().getName());
try {
result = provider.authenticate(authentication);
if (result != null) {
copyDetails(authentication, result);
break;
}
} catch (AccountStatusException e) {
// SEC-546: Avoid polling additional providers if auth failure is due to invalid account status
eventPublisher.publishAuthenticationFailure(e, authentication);
throw e;
} catch (AuthenticationException e) {
lastException = e;
}
}
As you can see, it loops over each AuthenticationProvider and passes in the Credentials. Hope that helps!
Philip
We are able to do something similar to what you're asking by extending AbstractUserDetailsAuthenticationProvider. There's an method retrieveUser(String _userName, UsernamePasswordAuthenticationToken _authToken) that you can override and put in your own custom logic. The return object is a UserDetails. So at this point you can create your own custom UserDetails and return it back to the framework (note: you can set your read-only attributes in this method as well).
At this point Spring Security will not have tried to authenticate using the password. They leave that to the additionalAuthenticationChecks(UserDetails _userDetails, UsernamePasswordAuthenticationToken _authToken) method that you can also override. Since this is where you would do your password validation it's ok to just skip the validation and let the method return. At this point your anonymous user will be validated.
Finally add this into your security.xml
<authentication-manager alias="authenticationManager">
<authentication-provider ref="appUserSecurityService" />
</authentication-manager>
I hope this helps!

Where exactly does Forms Authentication exist in the Http Pipeline?

Where exactly does Forms Authentication exist in the Http Pipeline?
This is handled by an HTTP module, System.Web.Security.FormsAuthenticationModule. If you look at the system-wide web.config file, c:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config, you can see where it's mentioned in the <httpModules> section. The site-specific web.config file will inherit the configuration in that file.
On each request, the module will look for an authentication cookie. If it's not present, the request is redirected to the login page. On a successful login, an authentication cookie is sent back to the browser. Then on subsequent requests, the browser will send the cookie, which will be validated by the module, and then the request is handled as usual.
Guess I should've thought of this first but it didn't dawn on me until I saw the answer from #Carl Raymond that I can just crack it open in reflector. So to answer my own question
public void Init(HttpApplication app)
{
if (!_fAuthChecked)
{
_fAuthRequired = AuthenticationConfig.Mode == AuthenticationMode.Forms;
_fAuthChecked = true;
}
if (_fAuthRequired)
{
FormsAuthentication.Initialize();
app.AuthenticateRequest += new EventHandler(this.OnEnter);
app.EndRequest += new EventHandler(this.OnLeave);
}
}
OnEnter calls the private method OnAuthenticate which passes in the application context and this is where it validates/writes out the Form Auth tickets.
In OnExit it checks the response for a Http Status Error Code 401 and if it finds it, that's when it redirects to the Login Url.

Resources