How to configure spring security with custom JAAS stack? - spring-security

I have followed this tutorial in order to add basic spring security to my spring mvcbasedweb app.
Before adding the spring security layer my app was protected using acustom SSO login module configured in my web.xml:
<login-config>
<auth-method>MyLoginModule</auth-method>
</login-config>
This login module takescare of redirecting to the login form, performing login etc. and isworking asexpected.
After adding the basic spring security layer the app is redirecting to my custom login page and when I authenticate pass me through yet another authentication using spring's standard "Login with Username and Password" form.
My question is how to configure spring to only use my login-config above to perform the authentication and remove it's redundant own "built in" form?

Sorry I haven't understood your scenario before. Check this to perform your authentication. You should register the user into the SecurityContextHolder.
Also visit the oficial spring 3.1 security reference.
The following example is for typical form web authentication (be sure to identify it with spring j_username/password):
<form id="loginForm" name="loginForm"
action="<c:url value='my_security_check'/>" method="POST">
...
<label for="user">The username</label><input type="text" name="j_username"/>
<label for="password">The password</label><input type='password'
name='j_password'/>
...
<input name="submitButton" type="submit" value="submit"/>
...
You have to define this security check in your spring security file:
<security:form-login login-page="/login"
default-target-url="/welcome"
login-processing-url="/my_security_check" />
<security:logout logout-url="/my_security_logout"
logout-success-url="/login" />
</security:http>
In my case I'm using Tiles i have to also add this to my mvc config file :
<mvc:view-controller path="/login" view-name="login" />
Example and source code : mkyong.com/spring-security/spring-security-form-login-example/

I found what I was looking for in the Spring Security reference. Specifically, the chapter on Java Authentication and Authorization Service (JAAS) Provider.

Related

How to login by cookie with Spring Security?

In my Spring Boot application, user information is encoded and stored in cookies. For every request the user sends, server just needs to parse cookie. If success, server extracts user info and let the request pass. How can I implement this procedure in Spring Security by implementing a custom authentication procedure?
I'm trying to switch from Shiro to Spring Security.
You can write a sub class of AbstractAuthenticationProcessingFilter:
Abstract processor of browser-based HTTP-based authentication requests.
and add this class to the filter chain, see Spring Security Reference:
You can add your own filter to the stack, using the custom-filter element and one of these names to specify the position your filter should appear at:
<http>
<custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
</http>
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/>

Spring Security 3.1

Could someone help me on this. appreciate your help.
I am using Spring security 3.1 with create-session="stateless" option.
Which throwing "InsufficientAuthenticationException" : "Full authentication is required to access this resource" exception of ExceptionTranslationFilter.
I am not able to understand what I am doing wrong and why I am getting this exception . As this exception stated that the credentials are not proper but I can see the credentials are going through request.Still I am getting 401 unauthorized
Fact is that the user is able to login properly & I get the message on console also. But again it is redirecting to login page due to access denied exception.
Here I am putting the code
Spring-Security.xml
<http entry-point-ref="negotiateSecurityFilterEntryPoint"
create-session="stateless" >
<intercept-url pattern="/user/loginuser" access="ROLE_ANONYMOUS"/>
<intercept-url pattern="/**" access="ROLE_USER"/>
<custom-filter ref="securityContextPersistenceFilter" after="BASIC_AUTH_FILTER" />
<custom-filter ref="ldapAuthFilter" position="CAS_FILTER" />
<custom-filter ref="databaseAuthFilter" position="FORM_LOGIN_FILTER" />
</http>
<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name='securityContextRepository'>
<bean class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<property name='allowSessionCreation' value='false' />
</bean>
</property>
</bean>
As far as I know, that's exactly what stateless is meant to do.
Once you set create-session parameter as stateless, on every http call the SecurityContextPersistenceFilter won't be even called (by default) or, even if you force it to be called according to your configuration, it won't be any session level security information in the SecurityContextHolder.
This stateless pattern is intended to be used in a Rest style architecture, where authentication and authorization information is sent on every request. Better said, I don't think that stateless session creation pattern should be used unless you are developing a full stateless application
I found a good post about this, Spring Security Session Management, look carefully section 2. When Is The Session Created?
So stateless session creation strategy does not fit to a classic login form pattern.
In your scenario, I guesss that what is happening is that, once the login request is completed and the request is authenticathed, it is probably redirecting to a kind of welcome page using an HTTP 301 or 302 redirect, redirection which again is not carrying authentication info, so ends redirecting again to login page.
If you simply use "ifRequired" as session-creation, or as it is the default value, just don't set it, I bet your login would end successfully and redirect to wherever it should correctly without asking to log in again. And, if you do it like this, avoid setting the SecurityContextPersistenceFilter, it is configured automatically.

Spring Security provides anonymous acces to all pages instead only one

I my sprig-security.xml I've got:
<security:http auto-config='true' create-session="stateless">
<security:intercept-url pattern="/registrate**" access="hasRole('ROLE_ANONYMOUS')" />
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<security:http-basic />
<security:csrf disabled="true"/>
</security:http>
The problem is that all protected pages are available for anonymous users, the only way to get access denied is to enter bad user's credentials, but with no credentials it will pass.
How to give anonymous user access to only "/registrate" page and give access to authorized user for rest of resources.
I've looked in Spring Docs and in the web. The only solution I've found is here and it didn't work for me.
The problem was in the program I tested my service with. The program was SoapUI 5.1.3.

How to have a super user using Spring Security Framework?

I am using Spring Security to control the authority in my web application.I imported the security tag in my code as below:
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
Then I am using the code block like this to control if the user have access to the specified button:
<sec:authorize ifAnyGranted="addUser">
<button type="button">Add User</button>
</sec:authorize>
With this code,only the user who have the addUser authority can see this button and use it.
Now my question is:Can we have a super user that even if it doesn't have the addUser authority,he still can see this button?
No, I don't think there is such feature built-in in Spring Security. You can either:
have a super user role (authority) that you check for in every authorization check, or
give your super user all possible authorities in your authentication provider or user details service.
I'm not really sure that it is the expected answer, but SpringSecurity has a notion of hierachy of roles. That mean you could create a super user role and declare it to contain addUser authority (among others).
That way, any user having the superUser authority will (among other permissions) see your button
References : From Hierarchical Roles in Spring Security reference manual you could write something like
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_SUPER_USER > ROLE_ADD_USER
</value>
</property>
</bean>
It seems as a missing requirement, thus I have created an issue in Spring Security repository:
https://github.com/spring-guides/top-spring-security-architecture/issues/5

spring security - mutiple authentications for differnt URL patterns

my application currently has one authentication defined for a specific URL, with a custom filter, where user is authenticated by extracting the user details from the URL (in the query string). This is working fine.
Now I want to add a new authentication using an identity certificate for a different URL pattern (the authentication is completely different from the first one, it has a differnt user details service etc). I saw there's already support for x509 cert authentication in spring security. I want to understand what is the best configuration I should do considering the following:
I want users access the different URL patterns to be authenticated by the relevant authentication, and not try first with one authentication and if that fails then try the other one. This is why I think I may need 2 different authentication managers?
My application must be in HTTPS for all URLs
I need to configure tomcat in a way where client authentication is required only for the specific URL pattern, not to all the application.
Here is what I have so far for the first authentication, any help would be appreciated:
security-applicationContext.xml:
<sec:http pattern="/urlAuth1" auto-config="false" entry-point-ref="url1EntryPoint">
<sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" requires-channel="https" />
<sec:custom-filter position="PRE_AUTH_FILTER" ref="urlPreAuthFilter"/>
</sec:http>
<bean id="urlPreAuthFilter" class="com.myapp.security.UrlPreAuthenticatedFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="urlPreAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="urlUserDetailsService" />
</bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="urlPreAuthProvider" />
</sec:authentication-manager>
Thanks!
EDIT - 30.01.13:
I added the following section to my security context.xml. When I debug my app when accessing both URLs patterns, I see that for first URL pattern (/urlAuth1) the getProviders() in the authenticationManager returns just one provider which is the urlPreAuthProvider, and for the second URL pattern (/certAuthTest) it returns two providers - the anonymous and preauthenticatedprovider which I guess are registered by default. For me this is OK since it means each pattern goes through the correct providers. I want to make sure I am not missing anything, does it seem right to you?
<sec:http pattern="/certAuthTest" auto-config="false">
<sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" requires-channel="https" />
<sec:x509 subject-principal-regex="CN=(.*?)," user-service-ref="certUserDetailsService"/>
</sec:http>
regarding the web.xml configuration for clientAuth, I'll do some more reading and see if this works. Thanks!
You can declare separate authentication manager beans for each URL pattern you want and then assign them to the individual filter chains using the authentication-manager-ref attribute on the <http /> element.
<http pattern="/someapi/**" authentication-manager-ref="someapiAuthMgr">
...
</http>
You can use the standard ProviderManager bean for the individual authentication managers.
To enforce HTTPS for all requests, you can use standard web.xml settings.
Client certificate authentication takes place when the SSL connection is established. So you either have it or you don't. Investigate the clientAuth tomcat connector setting. You can set it to "want" to ask for a client certificate but not require one for the SSL connection to succeed.

Resources