Spring Security for RESTful API - spring

I'm building a restful API using Spring 4.1.6 and spring-boot-starter-data-rest.
To make the rest api fully functional I need the last piece of the puzzle: security. Now I noticed spring has it's own spring-security-* packages that can aid with that task.
I tried using spring-security-config and spring-security-web and it works like a charm, with the exception that if the user is not authenticated, spring will redirect the user to login, thus giving a HTML login form.
Because it's a Restful API, I just need an error to be returned in a JSON object if the user lacks the credentials or does not have enough permissions to read a particular resource.
I'm sure I'm not the first to ask this question and searched all over the web for people asking the same thing, but couldn't quite find was I was looking for. So.. should I continue my research in this direction with spring-security, or should I find something?
Any advice is welcome,
thank you

To change the Login Form response to a custom Http Response you need to configure a custom http response handler for Http Security config. If you are using xml for your security configuration use the configuration shown below, failureHandler used is the one available in Spring Security package. Update the URL to match yours.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!-- Rest authentication entry point configuration -->
<http use-expressions="true" entry-point-ref="restAuthenticationEntryPoint">
<intercept-url pattern="/api/**" />
<sec:form-login authentication-failure-handler-ref="myFailureHandler" />
<logout />
</http>
<!-- Using default failure handler -->
<beans:bean id="myFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" />
</beans:beans>

Related

Spring SecurityXML. http tag inheritance

I have a security-spring.xml with some general rules applied for many urls and I want to make an exception for one specific url that also matches that pattern. Can I do it without copying the complete <http> tag?
What I tried is this:
<beans ...>
<http pattern="/a/b" xmlns="http://www.springframework.org/schema/security" >
<csrf disabled="true"/><!-- An exception I want to add -->
</http>
<http pattern="/a/**" xmlns="http://www.springframework.org/schema/security" ...someproperties >
<!-- General config for many urls -->
</http>
</beans>
Accessing /a/b without csrf token works but looks like it doesn't inherit any config properties from the /a/** pattern.
Is that how it's supposed to be (each http is independent) or is there a way to "append" this exception to /a/b and inherit the rest from the /a/**?
Spring-security version: 4.2.6
The <csrf> configuration element is a sub-element of the main container element for security configuration, i.e. the <http> element.
So yes, if you would like to have the Corss-site Request Forgery disabled / enabled for a configured sub-url, you have to duplicate all the necessary configuration elements.
One particular solution to avoid duplication would be to opt for a Java-based configuration.

How to set up server.xml in WebSphere Liberty with LDAP to match global security active similar to WAS 7.0 for spring apps

I have a spring app.
It is consistently giving me this error in websphere liberty. This is my login settings .
in web.xml for spring security.
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- ===== SECURITY CONFIGURATION ===== -->
<!-- All requests matching pattern below will bypass the security filter chain completely -->
<security:http pattern="/image/**" security="none"/>
<!-- security:http pattern="/login.jsp*" security="none" / -->
<!-- Defines who can access each URL. -->
<!--
Spring Security 3.0 introduced the ability to use Spring EL expressions as an authorization mechanism in addition to the simple use
of configuration attributes and access-decision voters which have seen before. Expression-based access control is built on the same
architecture but allows complicated boolean logic to be encapsulated in a single expression.
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/el-access.html
-->
<security:http auto-config="true" use-expressions="true">
<!-- URL restrictions (order is important!) Most specific matches should be at top -->
<!-- Don't set any role restrictions on login.jsp. Any requests for the login page should be available for anonymous users -->
<security:intercept-url pattern="/login.jsp*" access="isAuthenticated()" />
...
Anonymous access to the login page doesn't appear to be enabled. This is almost certainly an error. Please check your configuration allows unauthenticated access to the configured login page. (Simulated access was rejected: org.springframework.security.access.AccessDeniedException: Access is denied)
I have configured LDAP but I do not know how to tie LDAP settings to server authentication as similar to WAS 7.0 global security activation so the application is not able to authenticate .
Can someone give me further infomation as how the access-id in security settings relates to LDAP Realm.
<jaasLoginContextEntry id="system.WEB_INBOUND" loginModuleRef="HashLogin, certificate, hashtable, token, userNameAndPassword" name="system.WEB_INBOUND"/>
<jaasLoginContextEntry id="WSLogin" loginModuleRef="WSLoginId, certificate, hashtable, token, userNameAndPassword" name="WSLoginId" />
<jaasLoginModule id="WSLoginId" className="com.ibm.ws.security.common.auth.module.WSLoginModuleImpl" libraryRef="${com.ibm.ws.security.wim.*}"></jaasLoginModule>
</server>
I have looked at the Liberty profile documents so I would appreciate a more detailed information then linking me to IBM documents because I have read those and several information out in internet a lot and have exhausted all resources that I can do look up on so I would really appreciate a more detailed explanation which would explain how to implement global security and application security enablement as WAS 7.0 does when we configure LDAP repository in WAS . My LDAP is Microsoft Active Directory. And my application security is handled by spring container.
As resource I looked at this but this did not seem to help.
How to map security role to ldap group in websphere liberty profile
Here is how access-id in the Liberty profile can be defined assuming the LDAP server definition has realm name as ldapRealm in server.xml.
<!- Sample LDAP definition -->
<ldapRegistry id="TivoliLdap" host="myHost.rtp.raleigh.ibm.com" realm="ldapRealm" port="389" ldapType="IBM Tivoli Directory Server" ignoreCase="false" baseDN="o=mycompany,c=us">
</ldapRegistry>
<!-- Application binding sample for using access-id attribute for user or group element -->
<application-bnd>
<security-role name="Employee">
<user name="Bob" access-id="user:ldapRealm/Bob"/>
<group ame="developers" access-id="group:ldapRealm/developers"/>
</security-role>
</application-bnd>

Concurrent Session Control - Spring Security

HI I am trying to implement Spring Security: Concurrent Session Control to limit one session at a time. I see that I only need
<http>
...
<session-management>
<concurrency-control max-sessions="1" />
</session-management>
</http>
I get this from the reference http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-config . The problem that I am facing is that i get this error saying, "Configuration problem: No AuthenticationEntryPoint could be established. Please make sure you have a login mechanism configured through the namespace (such as form-login) or specify a custom AuthenticationEntryPoint with the 'entry-point-ref' attribute" I do not need to use a login page in the configuration here. I saw other posts, but I cannot find a solution to this problem. Please help me with a solution here. I will post my code below.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring- mvc.xsd">
<security:http>
<security:session-management>
<security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</security:session-management>
</security:http>

How to enable Spring Security Annotations not using app-Context.xml file?

I've implemented my Application using SecurityContextImpl as SecurityContext. anything works well (Authentication and Authorization).
Now I want to use Spring Security Annotations (#Secured , ...) , I my searched result in a single comment :"USE in your context.xml file"
is there any other way to embed security annotations using non-file-based ContextImpls?
Here's the config snippet you need. Not sure why you don't want to enable via XML.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns:security="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<security:global-method-security secured-annotations="enabled" />
</beans:beans>

404 when adding beans in the applicationContext xml file

I'm trying to learn Spring, Hibernate and Webflow.
Why is it that when I add beans to my applicationContext i get a 404 when I run the project.
Here's my context config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="roleService" name="roleService" class="ws.Service.RoleServiceImp" />
</beans>
Now when I add another bean, it goes 404. I'm not sure what's wrong. i.e:
<bean id="userService" name="userService" class="ws.Service.UserServiceImp" />
Am I missing something? Any help will be appreciated.
If an Web Spring Application can not start, for example if the context-xml contains a bean that does not exist, or a syntax error, then Spring will not "start" the context.
If you have a spring web application and the application does not start then, the whole spring web request handling stuff does not too. And when you not try to access an web page normally handled by the spring controllers the web server can not found this handler, so the web server says: not found - 404.
that is the answer to your question: "Why is it that when I add beans to my applicationContext i get a 404 when I run the project."
Anyway I believe you are more interested in why the application did not start:
have a look in the logs, there must be a stack trace
if you did not find the problem, with help of the stack trace, then add it to your question (or ask a new one).

Resources