I have a Spring 4.2.5 MVC REST Back-End with Spring Security 4.0.4, and I am using the "SiteMinder" example where I am expecting an authentication token.
<beans:bean id="tokenFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<beans:property name="principalRequestHeader" value="auth_token"/>
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService">
<beans:bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:property name="userDetailsService" ref="customUserDetailsService"/>
</beans:bean>
</beans:property>
</beans:bean>
I do have a "userDetailsService" details class, and this is working as expected for me, and the unit tests do not fail. However, I do want some exceptions, like for the. login pages and the like.
So, here is part of my spring-security.xml file:
<intercept-url pattern="/test/getStat/**" access="hasRole('WEB')" />
<intercept-url pattern="/test/getData/**" access="hasRole('WEB')" />
<intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/login/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/login/user/*/pwd/*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/index.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="index.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
I've tried access="permitAll" and "IS_AUTHENTICATED_ANONYMOUSLY" and several other tricks. It seems like every URL wants the token ... I just want url's to skip that check. So, not sure what I am missing.
Any help would be much appreciated.
Related
I have the following snippet
<http use-expressions="true" auto-config="false"
entry-point-ref="loginUrlAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager" disable-url-rewriting="false">
<!--<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter"
/> -->
<custom-filter position="FORM_LOGIN_FILTER"
ref="usernamePasswordAuthenticationFilter" />
<custom-filter position="LOGOUT_FILTER" ref="tapLockFilter" />
<intercept-url pattern="/session/**" access="permitAll" />
<intercept-url pattern="/deviceregistration/**" access="permitAll" />
<intercept-url pattern="/session/lock" access="hasRole('ROLE_MEMBER')" />
<intercept-url pattern="/app/resources/admin*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/app/SuperAppdashboard*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/app/*" access="hasRole('ROLE_MEMBER')" />
<!--<session-management invalid-session-url="/tizelytics/session/invalidSession"
session-authentication-error-url="/tizelytics/session/accessDenied" session-authentication-strategy-ref="sas">
</session-management> -->
<session-management invalid-session-url="/session/invalidSession"
session-authentication-error-url="/session/accessDenied"
session-fixation-protection="none">
<concurrency-control max-sessions="1"
expired-url="/session/accessExpired" />
</session-management>
</http>
When i run this on server it throws an exception saying
Unsupported configuration attributes: [permitAll, permitAll, hasRole('ROLE_ADMIN'), hasRole('ROLE_ADMIN'), hasRole('ROLE_MEMBER'), hasRole('ROLE_MEMBER')]
here is my access-decision-manager bean within the same xml
<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.access.vote.AuthenticatedVoter" />
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
If i remove the access-decision-manager-ref no exception is thrown the app launches correctly can anyone please advice?
Since you are defining your own accessDecisionManager, I don't see WebExpressionVoter as one of the beans in its list. WebExpressionVoter resolves strings like permitAll(), hasRole(), hasAuthority(), etc. So, your accessDecisionManager bean should be:
<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.access.vote.AuthenticatedVoter" />
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
<beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
I am working on a Spring-MVC project in which we are using Spring-Security for authentication, authorization. After recent upgrade of Spring-security to 4.0.1.RELEASE, there were some issues, but I was able to fix them by changing some stuff in the project. Now, the problem is the JSP tags I am using below is not working :
<sec:authorize access="isAnonymous()">
<div class="registerNow btn btn-info btn-lg btn-regBut">
<spring:message code="index.promo.list.item5"/></div>
</sec:authorize>
But If I replace the above with hasRole('ROLE_USER'), then it works, but if the user is already logged in, it does not make any sense to show the registration button. So why is that even if the IDE is suggesting the isAnonymous() it does not work, and what parameter should I pass to access, so that non-authenticated users only will see that button. Thanks a lot. :-)
security-applicationContext.xml :
<security:http pattern="/resources/**" security="none"/>
<security:http create-session="ifRequired" use-expressions="true" auto-config="false" disable-url-rewriting="true">
<security:form-login login-page="/login" username-parameter="j_username" password-parameter="j_password" login-processing-url="/j_spring_security_check" default-target-url="/dashboard" always-use-default-target="true" authentication-failure-url="/denied" />
<security:remember-me key="_spring_security_remember_me" user-service-ref="userDetailsService" token-validity-seconds="1209600" data-source-ref="dataSource"/>
<security:logout delete-cookies="JSESSIONID" invalidate-session="true" logout-url="/j_spring_security_logout"/>
<!-- <security:intercept-url pattern="/**" requires-channel="https"/> -->
<security:intercept-url pattern="/j_spring_security_check" access="permitAll" />
<security:port-mappings>
<security:port-mapping http="8080" https="8443"/>
</security:port-mappings>
<security:logout logout-url="/logout" logout-success-url="/" success-handler-ref="myLogoutHandler"/>
<security:session-management session-fixation-protection="migrateSession">
<security:concurrency-control session-registry-ref="sessionRegistry" max-sessions="5" expired-url="/login"/>
</security:session-management>
<security:csrf disabled="true"/>
</security:http>
<beans:bean id="rememberMeAuthenticationProvider" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<beans:constructor-arg index="0" value="_spring_security_remember_me"/>
<beans:constructor-arg index="1" ref="userDetailsService"/>
<beans:constructor-arg index="2" ref="jdbcTokenRepository"/>
<property name="alwaysRemember" value="true"/>
</beans:bean>
<beans:bean id="jdbcTokenRepository"
class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
<beans:property name="createTableOnStartup" value="false"/>
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<!-- Remember me ends here -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="LoginServiceImpl">
<security:password-encoder ref="encoder"/>
</security:authentication-provider>
</security:authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11" />
</beans:bean>
<beans:bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="LoginServiceImpl"/>
<beans:property name="passwordEncoder" ref="encoder"/>
</beans:bean>
</beans>
I have a web app where you can login with form-login or you can be pre-authenticated and be logged in like that. Both method work well but I only can find way to use a success handler with the form-login using the authentication-success-handler-ref property.
My question is, how can I call the success handler "mySuccessHandler" for the PRE_AUTH_FILTER in my security-app-context? I would guess I can call it as a property or something under the PreAuthenticatedProcessingFilter, preauthAuthProvider or the custom-filter.
Just need to go to different pages if the user has the role Teacher or Student.
<beans:beans xmlns="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.2.xsd">
<http pattern="/**" use-expressions="true" create-session="always">
<intercept-url pattern="/login.jsp*" access="permitAll" />
<intercept-url pattern="/**/ErrorPages/**" access="permitAll" />
<intercept-url pattern="/**/Students/**" access="hasAnyRole('STUDENT, TEACHER')" />
<intercept-url pattern="/**/Teacher/**" access="hasRole('TEACHER')" />
<intercept-url pattern="/**/Login/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**/Js/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**/Css/**" access="permitAll" />
<intercept-url pattern="/**/Img/**" access="permitAll" />
<intercept-url pattern="/**/api/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/**" access="denyAll" />
<custom-filter position="PRE_AUTH_FILTER" ref="PreAuthenticatedProcessingFilter" />
<access-denied-handler
<form-login
username-parameter="idnumber"
password-parameter="password" login-processing-url="/athuga_innskraningu"
login-page='/login.jsp'
authentication-failure-handler-ref="myAuthErrorHandler"
authentication-success-handler-ref="mySuccessHandler"
always-use-default-target='true'
authentication-failure-url="/login.jsp?login_error=true"/>
<logout logout-url="/utskra/" logout-success-url="/login.jsp"/>
</http>
<beans:bean id="mySuccessHandler" class="is.inna.rest.login.AuthenticationSuccess"/>
<beans:bean id="myAuthErrorHandler" class="is.inna.rest.login.AuthenticationFailure"/>
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<beans:bean name="myUserDetailsService" class="is.inna.rest.login.UserDetailServiceLogin" />
<beans:bean id="userDetailsServiceWrapper" class="is.inna.rest.login.UserDetailServicePreAuth" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailsService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
<authentication-provider ref="preauthAuthProvider" />
</authentication-manager>
<beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<beans:property name="preAuthenticatedUserDetailsService" ref="userDetailsServiceWrapper"/>
</beans:bean>
<beans:bean id="PreAuthenticatedProcessingFilter" class="is.inna.rest.login.PreAuthenticatedProcessingFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
Your requirement is to redirect user to different pages depending on the role. You can do this using authentication success handler also. Refer the sample success handler class I have written. You always have access to Authentication object in the overridden onAuthenticationSuccess method. You can get the authorities and role of logged in user and depending upon it, you can always redirect user to appropriate page.
Hope this helps.
I am trying to setup a handler for UsernameNotFoundException & BadCredentialsException for Password Grant oauth flow (Spring-Outh). The purpose for the handler, is whenever any one of those exceptions are thrown increment a counter in the DB.
I am not sure at what point this handler needs to setup.
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="ROLE_USER" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- The OAuth2 protected resources are separated out into their own block so we can deal with authorization and error handling
separately. This isn't mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/public/**" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/public/registration" access="ROLE_USER,SCOPE_READ" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<http use-expressions="true" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint">
<intercept-url pattern="/public/registration/activation/**" access="permitAll" />
</http>
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
<sec:authentication-provider ref="daoProvider">
</sec:authentication-provider>
</authentication-manager>
<beans:bean id="customUserDetailService" class="com.cointraders.api.services.UserDetailsServiceImpl" />
<beans:bean id="daoProvider" class="com.cointraders.api.daoauthproviders.CustomDaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="customUserDetailService"/>
<beans:property name="passwordEncoder" ref="passwordEncoder" />
</beans:bean>
<beans:bean id="clientDetails" class="org.springframework.security.oauth2.provider.JdbcClientDetailsService">
<beans:constructor-arg ref="dataSource" />
</beans:bean>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:refresh-token />
<oauth:client-credentials/>
<oauth:custom-grant token-granter-ref="randomTokenGrant" />
</oauth:authorization-server>
AuthenticationManager is a very simple interface. I don't think anyone needs help implementing that. And the authorization server configuration DSLs have explicit spots where you plugin an AuthenticationManager (e.g. The AuthorizationServerEndpointsConfigurer in Java, like here: https://github.com/spring-projects/spring-security-oauth/blob/master/tests/annotation/jdbc/src/main/java/demo/Application.java).
I changed spring security default '/j_security_check' url to '/check', and when I login into my system, then, I type url 'http://www.example.com/users/list' it will go to page right, but when I add 'check' string append to this url, like 'http://www.example.com/users/list/check', it will go into my custom UsernamePasswordAuthenticationFilterCustom filter, any url append "check" will do this, I don't know why.
<beans:beans xmlns="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.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- HTTP security configurations -->
<http pattern="/favicon.ico" security="none"/>
<http pattern="/statics/**" security="none"/>
<http pattern="/forgotPasswords/**" security="none"/>
<http pattern="/messages/**" security="none"/>
<http pattern="/sessions/**" security="none"/>
<!--<http pattern="/preferences/reLogin" security="none"/>-->
<http pattern="/javascript/message/**" security="none"/>
<http pattern="/dualLogin" security="none"/>
<http pattern="/inbound" security="none"/>
<http pattern="/twilio/**" security="none"/>
<http pattern="/download/async/**" security="none"/>
<beans:bean id="usernamePasswordAuthenticationFilterCustom" class="com.everbridge.platform.security.extension.UsernamePasswordAuthenticationFilterCustom">
<beans:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
<beans:property name="passwordParameter" value="password"/>
<beans:property name="usernameParameter" value="username"/>
<beans:property name="allowSessionCreation" value="true"/>
<beans:property name="filterProcessesUrl" value="/check"/>
<beans:property name="authenticationManager" ref="authenticationManagerCustom"/>
<beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler"/>
<beans:property name="userService" ref="userService" />
<beans:property name="roleService" ref="roleService" />
<beans:property name="accountService" ref="accountService" />
<beans:property name="featureService" ref="featureService" />
<beans:property name="moduleService" ref="moduleService"/>
<beans:property name="permissionService" ref="permissionService"/>
</beans:bean>
<http entry-point-ref="authenticationEntryPoint" auto-config="false" use-expressions="true">
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<custom-filter position="FORM_LOGIN_FILTER" ref="usernamePasswordAuthenticationFilterCustom" />
<custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR" />
<custom-filter ref="afterLoginInterceptor" after="LAST" />
<logout logout-url="/logout" />
<intercept-url pattern="/login" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/switch" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/api/**" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/m/switcher" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/m" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/logout" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/check" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/registers/**" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/preferences/**" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/information/**" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>
<access-denied-handler ref="accessDeniedHandlerCustom"/>
<session-management session-authentication-strategy-ref="sas" />
</http>
<beans:bean id="authenticationSuccessHandler" class="com.everbridge.platform.setting.handler.extension.AuthenticationSuccessHandlerCustom">
<beans:property name="targetUrl" value="/dashboard" />
</beans:bean>
<beans:bean id="sas"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
</beans:bean>
<beans:bean id="concurrencyFilter" class="com.everbridge.platform.security.extension.CustomConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/login" />
<beans:property name="logoutHandlers">
<beans:list>
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"></beans:bean>
<beans:bean class="com.everbridge.platform.security.extension.CustomLogoutHandler"></beans:bean>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="authenticationFailureHandler" class="com.everbridge.platform.setting.handler.extension.AuthenticationFailureHandlerCustom"/>
<beans:bean id="authenticationEntryPoint"
class="com.everbridge.platform.security.extension.AjaxAwareAuthenticationEntryPoint">
<beans:constructor-arg value="/login"/>
</beans:bean>
<beans:bean id="filterSecurityInterceptor"
class="com.everbridge.platform.security.extension.FilterSecurityInterceptorCustom">
<beans:property name="authenticationManager" ref="authenticationManagerCustom" />
<beans:property name="accessDecisionManager" ref="accessDecisionManagerCustom" />
<beans:property name="securityMetadataSource" ref="securityMetadataSourceCustom" />
</beans:bean>
<beans:bean id="afterLoginInterceptor"
class="com.everbridge.platform.portal.filter.AfterLoginInterceptor">
<beans:property name="accountService" ref="accountService" />
<beans:property name="roleService" ref="roleService" />
<beans:property name="userService" ref="userService" />
</beans:bean>
<beans:bean id="accessDecisionManagerCustom" class="com.everbridge.platform.security.extension.AccessDecisionManagerCustom"/>
<beans:bean id="securityMetadataSourceCustom" class="com.everbridge.platform.security.extension.InvocationSecurityMetadataSourceServiceCustom" init-method="loadResources">
<beans:property name="operationService" ref="operationService"/>
<beans:property name="permissionService" ref="permissionService"/>
<beans:property name="resourceService" ref="resourceService"/>
<beans:property name="roleService" ref="roleService"/>
<beans:property name="featureService" ref="featureService"/>
</beans:bean>
<beans:bean id="accessDeniedHandlerCustom" class="com.everbridge.platform.security.extension.AccessDeniedHandlerCustom">
<beans:property name="errorPage" value="/error401" />
</beans:bean>
<authentication-manager alias="authenticationManagerCustom"/>
Tony, first you need to define the page where your user will be authenticated, because the URL /j_security_check is the URL where Spring Security will check validation.
Try define your logic to auth:
<security:form-login login-page="/login" always-use-default-target="true" login-processing-url="/check" default-target-url="/dashboard" authentication-failure-url="/login.jsp?login_error=1" />