In our application we are using Spring Security and we observed that if the role names are not prefixed with ROLE , it does not work.
Our roles are configured in DB and there is no restriction on the name given to a role.
Is there any work around to avoid the ROLE prefix to roles?
You can find a solution here: Spring Security – adding a custom Role Prefix, according to which you just need to configure the RoleVoter:
<beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value="" />
</beans:bean>
See also Spring Security Role Prefix and Custom User Details Service.
As for me, I haven't noticed this behavior.
In my project I'm using Spring Security 3.1.4.RELEASE with Spring 3.2.3.RELEASE. And my securityContext.xml contains the following lines:
<security:http auto-config="false" use-expressions="true" access-denied-page="/denied.do"
entry-point-ref="authenticationEntryPoint">
<security:intercept-url pattern="/index.do" access="hasAnyRole('PROJECT_REVIEW', 'PROJECT_ADMINISTRATOR')"/>
<!-- Skipped -->
<security:intercept-url pattern="/**" access="hasAnyRole('PROJECT_REVIEW', 'PROJECT_ADMINISTRATOR')"/>
<!-- Skipped -->
</security:http>
So, I'm using my custom roles PROJECT_REVIEW, PROJECT_ADMINISTRATOR. And it works fine.
Could you please tell what error do you get?
Related
We use keycloak as our identity and access provider that is connected with spring security by keycloak's spring security adapter. We realized that the session id does not change when a user logs in the application which is an open door for session fixation attacks. Both keycloak and spring security provide solutions for preventing session fixation but when I use both in combination none of them works properly.
From keycloak's documentation:
turn-off-change-session-id-on-login
The session id is changed by default on a successful login on some platforms to plug a security attack vector. Change this to true if you want to turn this off This is OPTIONAL. The default value is false.
I didn't turn off this feature but the session id still remains the same after login procedure.
Spring security comes along with two implementations of the SessionAuthenticationStrategy, ChangeSessionIdAuthenticationStrategy and SessionFixationProtectionStrategy, but none of them does the trick.
In the keycloak doku you can find a hint that "SessionFixationProtectionStrategy is currently not supported" but there is no advice how to deal with the session fixation risk in this setup. But according to this hint it should still be possible to change the session id with spring security with the consequence that "universal log out will not work" anymore. But even this I don't get to work (maybe we could go with the trade-off and lose the universal logout)
I tried changing the session id with spring security on some ways (extraction of the configuration file):
overwrite default session management filter by following this instructions
<http use-expressions="true" auto-config="false" entry-point-ref="keycloakAuthenticationEntryPoint">
[...]
<!-- changeSessionId and newSession have no result at all -->
<session-management session-fixation-protection="none"/>
<session-management session-authentication-strategy-ref="sessionAuthenticationStrategy"/>
<custom-filter ref="sessionManagementFilter" position="SESSION_MANAGEMENT_FILTER"/>
[...]
</http>
<beans:bean id="sessionAuthenticationStrategy"
class="org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy"/>
<beans:bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
<beans:constructor-arg name="securityContextRepository" ref="securityContextRepository"/>
<beans:constructor-arg name="sessionStrategy" ref="sessionAuthenticationStrategy"/>
</beans:bean>
Overwrite default session management filter by this instruction
<http ...>
<session-management session-authentication-strategy-ref="sessionStrategy"/>
</http>
<bean id="sessionStrategy" class="org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationSessionStrategy"/>
Changing the behaviour of the default session management filter according to spring's documentation
<http use-expressions="true" auto-config="false" entry-point-ref="keycloakAuthenticationEntryPoint">
[...]
<!-- changeSessionId and newSession have no result at all -->
<session-management session-fixation-protection="changeSessionId"/>
[...]
</http>
Any hints are appreciated about preventing session fixation within a keycloak spring security environment.
I want to integrate LDAP in my spring application.
Requirement:- On request it should divert to my login page then ask for user/password. Then on submit it should authentication from LDAP.
Thanks
There is a special project in Spring called Spring Security for this purpose. The core functionality is built as a set of servlet API filters. There are multiple connectors for user's database (LDAP, DB, Active Directory, etc.) Here you can see how to add a basic conf. Your conf may looks like this:
<http use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login />
<logout />
</http>
Note that I prefer SpEL expressions for security rules. And here you can see how to add LDAP.
Hope it helps.
Along with that you also need other LDAP configuration like this
<ldap-server url="ldap://localhost:10389/dc=example,dc=com" />
<authentication-manager alias="authenticationManager"
erase-credentials="true">
<ldap-authentication-provider
user-dn-pattern="uid={0},ou=people" group-search-base="ou=groups"
group-search-filter="(members={0})">
</ldap-authentication-provider>
</authentication-manager>
I need to customize my authentication process in such manner:
Client sends request (REST API) with a "special" URL param
Server calls third-party service passing a param and receiving user name
Server lookups database by name and this is authenticated principal.
I split my server side (2+3) on two parts - custom filter for (2), that obtains user name - and a custom userdetailservice for(3) that builds principal by looking up name in database.
But I cannot build my security.xml correctly - every time it seems that it doesn't process filter at all. I think the problem is in the first (http) node, but I cannot understand what position should I set up for filter. Here is my config:
<http use-expressions="true" auto-config="true" authentication-manager-ref="authenticationManager">
<intercept-url pattern="/*" access="isAuthenticated" />
<custom-filter ref="casServiceTicketFilter" position="FIRST"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="wliAuthenticationService"/>
</authentication-manager>
<b:bean id="casServiceTicketFilter" class="org.WLICASAuthenticationFilter">
<b:property name="casTicketValidateURL" value="${cas.ticket.validate.url}"/>
<b:property name="authenticationManager" ref="authenticationManager"/>
</b:bean>
<b:bean id="wliAuthenticationService" class="org.WLIUserDetailService"/>
PS- Please don't tell me that Spring has CAS support out-of-the-box. It's a bit various configuration so I need to create my own implementation of service ticket validator
Your custom authentication filter shouldn't be first in the filter chain. It needs to come after the SecurityContextPersistenceFilter. Use
<custom-filter ref="casServiceTicketFilter" after="SECURITY_CONTEXT_FILTER"/>
instead.
If you enable debug logging, you should be able to see clearly what order the filters are called in for each request and whether yours is invoked.
Let me explain my problem.
I have implemented a site in AngularJS that is accessed like this:
http://localhost:8080/example/resources/#/
Here we can call different pages, for example a Login page:
http://localhost:8080/example/resources/#/login
admin page:
http://localhost:8080/example/resources/#/admin
user page:
http://localhost:8080/example/resources/#/user
Now, I have implemented spring security in the example in order to catch every call and check if it has ROLE_USER privileges. So far so good, I have done it like this configuration in Spring security context file:
<security:http create-session="stateless" entry-point-ref="restAuthenticationEntryPoint"
authentication-manager-ref="authenticationManager">
<security:custom-filter ref="customRestFilter" position="BASIC_AUTH_FILTER" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
</security:http>
This configuration checks for every url called, if the user has the proper ROLES, and it works fine, throws 401 Unauthorized page.
The problem I`m having is that when I put the login page to be accessed by everybody I'll do it this way:
<security:http create-session="stateless" entry-point-ref="restAuthenticationEntryPoint"
authentication-manager-ref="authenticationManager">
<security:custom-filter ref="customRestFilter" position="BASIC_AUTH_FILTER" />
<security:intercept-url pattern="/login**" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
</security:http>
But I dont know why spring security is not catching this URL. Maybe Angular manages the URL differently.
Finally i have tried deleting the <security:intercept-url pattern="/**" access="ROLE_USER" /> and giving /login** access to ROLE_USER only, but this page was not found. Does anybody know what could be happening here?
Thanks in advance!!!
I wrote a little sample application that illustrates how to integrate AngularJS with Spring Security by exposing the session id as an HTTP header (x-auth-token). The sample also provides some (simple) authorization (returning the roles from the server) so that the client AngularJS application can react to that. This is of course primarily for user-experience (UX) purposes. Always make sure your REST endpoints have property security.
My blog post on this is here.
Here is the Spring Security intercept-url configuration:
<intercept-url pattern="/**.html"
access="ROLE_USER" requires-channel="https" />
I want to make requires-channel="any" for local environment.
Is it possible to add absolute URL in the pattern?
You can use Spring bean definition profiles to achieve that.
<beans profile="local">
</beans>
It's a new feature. Take a look at the entry in Spring Source blog: http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/