spring security 3.0 restfull authentification for mobile client - spring

We have an existing jsf/spring application that uses spring security for authentication and authorization.
Now we want to add a restful web service layer, to be used by a mobile client (native android app.) The existing authentication process uses j_spring_security_check and a custom filter.
Can I handle the restful api authentication and authorization within the same context? If yes, how?

One possibility is to create another security configuration for the API realm. Configure it to HTTP BASIC authentication (if that suits you and if API is served over https).
For example:
<http use-expressions="true" pattern="/api/**" realm="API Realm" create-session="stateless">
...
<http-basic />
...
<logout logout-url="/api/logout" />
</http>
EDIT:
As per commenter's comment, I'm correcting my answer: this method unfortunately won't work in Spring Security 3.0 because multiple http elements in Spring Security config were added in 3.1.

Related

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.

Support SAML SSO and normal login

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.

Public & Private REST APIs with Spring Security

I have a REST Web Service written with Spring 3.2 that is secured with CAS via Spring Security, and I would like to have it provide an identical private, internal API that could be consumed by other servers on our private network without requiring authentication.
For example, these two endpoints /app/public/people/{id} and /app/private/people/{id} would both map to the same handler but the latter would bypass security and the former would require CAS authentication.
Can I just put both in the same #RequestMapping annotation and specify different security intercepts? For example,
security intercepts:
<security:intercept-url pattern="/private/**" access="permitAll() />
<security:intercept-url pattern="/public/**" access="isAuthenticated()" requires-channel="https"/>
request mapping:
#RequestMapping(value={"/public/people/{id}", "/private/people/{id}"})
What about using IP address to distinguish between access from private and public network? Then you can define just one endpoint for both. For an example, if you’re private network is 192.168.1.0/24, then:
<security:intercept-url pattern="/**"
access="isAuthenticated() or hasIpAddress('192.168.1.0/24')"
requires-channel="https" />
If you have Servlet container behind a reverse proxy, don’t forget to set X-Forwarded-For (or X-Real-IP) header and configure your container to use it; otherwise Spring Security will see IP of the reverse proxy, not a client.

Securing REST API with Spring Security

I'm trying to implement a REST API for my Spring application. As there are resources which might not be accessed by everyone, I need a security layer.
Within this application I'm already using Spring Security (which works perfectly fine) for securing my web application.
I've added the following http configuration to my spring-security.xml:
<http pattern = "/api/**" use-expressions = "true" disable-url-rewriting = "true">
<http-basic />
</http>
So I would assume that all request that are made to URLs starting with api/ will be secured.
Problem is that I can access my secured methods without any authentications. But if I use a REST client to access it, I receive this error:
message: Full authentication is required to access this resource
description: This request requires HTTP authentication.
I have no idea how to proceed. What is the best way to secure a REST API using Spring Security?
If you use Spring Security in your application, you, probably, already have an <http> section in one of your Spring config files. You can use this section to secure your REST API.
The <http> does not secure anything on its own. You have to add <intercept-url> rules inside it:
<intercept-url pattern="/api/**" access="hasRole('ROLE_USER')" />
There is a tuto on the official site of Spring. It is a little more complicated :
Official Spring Tuto
Just use Spring Security. In <http> tag add: <security:intercept-url pattern="your url" access="hasAnyRole('Your_User_Role1', 'Your_User_Role2')" />.
Or try use annotations. In your spring-config.xml enable security annotations: <security:global-method-security jsr250-annotations="enabled" pre-post-annotations="enabled" secured-annotations="enabled"/>
and in Controller add #PreAuthorize :
#PreAuthorize("hasAnyRole('Your_User_Role1', 'Your_User_Role2')")
#RequestMapping(value = "/address_planing/load_employee_info")

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>

Resources