Support SAML SSO and normal login - spring

I have an application which is accessed by two types of users, internal and external.
I need to authenticate external users using SAML.
I need to authenticate internal users with the normal form-based login. My application need to support both types of users. I use spring security frame work.
Is it possible to support both types of users? if so can you suggest the approach at high level? Thanks.

You can easily enable support for both form and SAML authentication with configuration similar to this:
<http entry-point-ref="authenticationEntryPoint" authentication-manager-ref="authenticationManager">
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
<form-login login-page="/login" />
<custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
<custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
</http>
Make sure that your AuthenticationManager contains the samlAuthenticationProvider. And of course include other configuration parts from the Spring SAML sample application.
You can then create your custom login page which presents user with username+password fields for form-based authentication and a link/picture (or multiple of them) which initialize authentication with the IDP (by redirecting user to scheme://host:port/saml/login?idp=selectedIdpEntityId).
Your users then decide which one to use - depending on whether they's internal or external.
The part of Spring SAML documentation touching on this subject is in chapter Spring Security integration.

Related

Share Spring Security Context across multiple http sections

I have a situation where I have the basic application being served on the main endpoint (/**). I use spring security to authenticate the user before serving any further resources. The authentication is done with a login form.
But specifically the endpoint (/lti/**) is being used in a different Http Section. There, Spring security handles the authentication using OAuth.
After authentication on the /lti/** endpoint, the user is expected to load my entire application in an iFrame. This means access to all resources protected by the 1st Http-section.
Now the problem here is even though the user authenticated using OAuth creds for loading the app from /lti/**, and I set all appropriate user roles, when the application loads in the iFrame and tries to access any resources, it redirects to the login screen as directed by the 1st Http-section (The succeeding calls are through AJAX if that helps, but you can see the response in the dev tools).
Based on my research so far, the Security Context is not shared among different entry points. Different firewalls are instantiated so the Security context itself is re-initiated.
Here's a bit of my Security context:
<security:http pattern="/lti/**" use-expressions="true" entry-point-ref="oAuthProcessingFilterEntryPoint">
<security:headers>
<security:frame-options disabled="true"/>
</security:headers>
<security:intercept-url pattern="/**" access="hasRole('ROLE_OAUTH')"/>
<!-- Filter -->
<security:custom-filter ref="oAuthProcessingFilter" before="ANONYMOUS_FILTER"/>
<!-- Disable CSRF -->
<security:csrf disabled="true"/>
</security:http>
<security:http>
<security:intercept-url ... />
....
<security:form-login
authentication-success-handler-ref="authenticationSuccessHandler"
login-page=............"/>
<security:logout ................./>
<security:session-management invalid-session-url="............." session-authentication-error-url="................">
</security:session-management>
<!-- Enable csrf protection -->
<security:csrf/>
</security:http>
Any approach that will work or have any ideas how I ccan tackle the situation?
SecurityContext is populated in every request, the FilterChain set it up at the beginning of the request by using the SecurityContextPersistenceFilter. By deafult, this filter store the authentication data in the HttpSession.
The users are authenticated in a page an then you load an Iframe which starts a different HttpSession (you could check this if you watch the sessionids).
Then you have several options:
Do not use an Iframe. The best option, if it is not a must.
Configure a default RememberMe filter. the problem is that the users will be remembered in each session, until the cookie expires.
Store the SecurityContext in a more persistent way than the session.
Summarizing, I think that your problem is not about different entry points, its about different sessions.

Spring REST Basic Authentication Design Approach

Environment :
Spring 4
Spring Security 4
Spring MVC 4
Hibernate 4
MySQL
Issue :
Below is the requirement :
1)We are developing a Spring REST service for inventory management.
2)This web service will be consumed by .NET client. (or may be mobile device in future)
3)The users of REST service need to be authenticated. The user will use login form displayed by .NET client and if authentication is successfull , he will be
allowed to consume REST API.
4)If authentication fails , user won't be allowed entry into REST service.
Now we have decided to use Basic Authentication for this.
My question is : How do we achieve this using Spring MVC REST and Spring security ?
Below is my first attempt :
application-security.xml
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/usermanagement/authenticate" access="permitAll"/>
<intercept-url pattern="/abhishek/*" access="hasRole('ROLE_ADMIN')"/>
<http-basic/>
<csrf disabled="true"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="Atul" password="12345" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
Following is the flow happening right now :
1)The /authentication API looks up user in Db and returns Http Status code 201(success ) or 401 (failure) accordingly. (this url is unsecured)
2)If success , client puts username/password as Authorization header (which is used in login) and sends this header for future Http requests.
3)Now once next request comes (this is secured), spring security comes into picture and again authentication happens here.
But this time it will be Spring provided.
4)So there are two authentication mechanism are being used .
5)I know I am messing up here , but not able to decide on what is the correct approach to design this.
6)How can client be provided the authentication capability by hooking into Spring security ? He needs to know authentication success/failure
immediately after he logs in.
Please help since I am struggling a lot on this.

Spring Security 4: Allowing anonymous access and authenticated access on same url

I have a Jersey 2 application which I'm trying to secure using Spring Security 4 and HTTP Basic authentication.
The controller class is a Spring bean and is injected into the Jersey Rest Resource. I'm using Spring Pre-Post-annotations on the controller's methods and tried out the following configs:
<security:global-method-security pre-post-annotations="enabled" />
<security:http>
<security:http-basic />
<security:intercept-url pattern="/**" access="hasRole('USER')" />
<security:csrf disabled="true"/>
</security:http>
Problem: Works fine with http-basic authenticated users, the annotated methods (#PreAuthorize("hasRole('USER')")) are secured and only work when the correct credentials are provided. BUT: Anonymous access on other resources under /** is not possible anymore (which is correct, but which I want to have).
Using
<security:intercept-url pattern="/**" access="permitAll" />
instead, every user is handled as anonymous, even though they are providing the correct credentials via HTTP Basic. So even a user with the correct role cannot access the annotated method, a AccessDeniedException is thrown.
What I want: Every user should be allowed to access all resources under "/**". If he's authenticated via HTTTP Basic and has sufficient rights, the annotated method can be called. If he's not authenticated or authorized, an AccessDeniedException should be thrown.
How do I have to configure the Spring security <http> section?

spring controller accept only local requests

Is there any easy way in Spring Security to lock down an #Controller to only accept requests from the same (local) host?
I was looking at this post:
Securing servlet URL without using username password authentication
However, I was wondering if that is actual best practice vs. some other security measure.
You can use hasIpAddress expression in the filter security interceptor.
<http use-expressions="true">
<intercept-url pattern="/**" access="hasIpAddress('127.0.0.1/32')"/>
...
</http>

Spring Security in a Stateless webapp? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
create-session stateless usage
Im just beginning experimenting on Spring Security, on version 3.1, and im wondering how to achieve authentication with a stateless webapp.
http-basic and digest come to mind, and i've tried them, but i dislike the inability to logout like the form authentication without closing the browser.
I currently have a working stateless webapp with form-based authentication using spring security (which makes it stateful by storing auth stuffs in session perhaps ?), and i wonder what are the strategies that i could research on to make spring security work without making use of http sessions ?
I realize that there's a <http create-session="stateless" ..>, but there must be something that needs more doing because the app stops working correctly after i tried that, by keep authenticating me when accessing protected resources.
Here's my config :
<http use-expressions="true" create-session="stateless">
<form-login login-page="/login"
login-processing-url="/static/j_spring_security_check"
authentication-failure-url="/login?login_error=t" />
<logout logout-url="/static/j_spring_security_logout"/>
<intercept-url pattern="/person/test/**"
access="isAuthenticated() and principal.username=='albertkam'"
/>
<intercept-url pattern="/person/**" access="hasRole('ROLE_NORMAL')"/>
<remember-me
key="spitterKey"
token-validity-seconds="2419200"/>
</http>
With create-session="stateless" :
accessing http://myhost:8080/mycontext/person/blah
goes to login page
returns to homepage url http://myhost:8080/mycontext after logging in (i expect it returns to the protected resource)
Without create-session="stateless", which defaults to ifRequired (stateful) :
accessing http://myhost:8080/mycontext/person/blah
goes to login page
returns to the protected url http://myhost:8080/mycontext/person/ blah after logging in (this is correct behaviour , but stateful)
You can use always-use-default-target="false" on <form-login>to prevent going to default page after successful login.

Resources