How to solve Spring security misconfiguration: incorrect request matcher type? - spring-security

I have this Spring security configuration:
<?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:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
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.1.xsd ">
<http pattern="/api/swagger-ui.html" security="none" xmlns="http://www.springframework.org/schema/security"/>
<http pattern="/api/webjars/**" security="none" xmlns="http://www.springframework.org/schema/security"/>
<http pattern="/api/swagger-resources/**" security="none" xmlns="http://www.springframework.org/schema/security"/>
<http pattern="/api/v2/api-docs" security="none" xmlns="http://www.springframework.org/schema/security"/>
<http pattern="/api/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false"/>
<intercept-url pattern="/api/**" access="IS_AUTHENTICATED_FULLY"/>
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</constructor-arg>
</bean>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="sample"/>
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>
<oauth:resource-server id="resourceServerFilter" resource-id="sample" token-services-ref="remoteTokenServices"/>
<bean id="remoteTokenServices" class="org.springframework.security.oauth2.provider.token.RemoteTokenServices">
<property name="checkTokenEndpointUrl" value="${oauth.check.token.url}"/>
<property name="clientId" value="${oauth.client:crdb}"/>
<property name="clientSecret" value="${oauth.secret:secret}"/>
</bean>
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
</authentication-manager>
<oauth:expression-handler id="oauthExpressionHandler"/>
<oauth:web-expression-handler id="oauthWebExpressionHandler"/>
</beans>
Fortify returns to me Spring security misconfiguration: incorrect request matcher type on line 9, 10, 11, 15. Can someone give me a point how to solve this issue? It seems there is a some path problem, but Im not so familiar with fortify, so I dont know how to solve this issue.

it seems like you have problem using <http/> tag used for configuration. Look closely whether you are using valid attributes related to that tag. You can simply identify the available properties/attributes for that by clicking on the tag.
It seems like xmlns="http://www.springframework.org/schema/security" this is making error because <http> does not have xmlns property.
You also don't need to define it in every http.
Try removing xmlns property from <http> tag and it should work.
For Reference: Spring Security XML Configuration
Available <http> attributes for configuration:
<http pattern=""
name=""
access-decision-manager-ref=""
authentication-manager-ref=""
auto-config=""
create-session=""
disable-url-rewriting=""
entry-point-ref=""
jaas-api-provision=""
once-per-request=""
realm=""
request-matcher=""
request-matcher-ref=""
security=""
security-context-repository-ref=""
servlet-api-provision=""
use-expressions=""/>

Related

How InMemoryTokenStore works with Spring Security OAuth2 and Is this the safest way from hacking perspective?

I am new to Spring Security OAuth2 using version 2.0.10.RELEASE implementation. I developed code using 'InMemoryTokenStore' and I'm impressed with the way it works (it creates access_token, 'refresh_token' etc..), but I don't have enough understanding on how it works yet. Can anyone please help to know / provide understanding on how it works?
Is 'InMemoryTokenStore' the safest implementation from hacking perspective? I also see there are many implementation provided by OAuth2 like JdbcTokenStore, JwtTokenStore,KeyStoreKeyFactory. I don't think storing access_token into the database in the great idea like JdbcTokenStore does.
Which Implementation we should follow and why ?
spring-security-oauth2.xml file
<?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:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
<http pattern="/oauth/token" auto-config="true" use-expressions="true" create-session="stateless" authentication-manager-ref="authenticationManager"
xmlns="http://www.springframework.org/schema/security" >
<!-- <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" /> -->
<intercept-url pattern="/oauth/token" access="permitAll" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<!-- Added this to fix error -->
<sec:csrf disabled="true" />
</http>
<http pattern="/resources/**" auto-config="true" use-expressions="true" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/resources/**" method="GET" />
<!-- <intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_FULLY" /> -->
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<!-- Added this to fix error -->
<sec:csrf disabled="true" />
</http>
<http pattern="/logout" create-session="never" auto-config="true" use-expressions="true"
entry-point-ref="oauthAuthenticationEntryPoint"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/logout" method="GET" />
<sec:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<!-- Added this to fix error -->
<sec:csrf disabled="true" />
</http>
<bean id="logoutSuccessHandler" class="demo.oauth2.authentication.security.LogoutImpl" >
<property name="tokenstore" ref="tokenStore"></property>
</bean>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="springsec/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
</bean>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<bean id="clientDetails" class="demo.oauth2.authentication.security.ClientDetailsServiceImpl"/>
<authentication-manager id="userAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="customUserAuthenticationProvider">
</authentication-provider>
</authentication-manager>
<bean id="customUserAuthenticationProvider"
class="demo.oauth2.authentication.security.CustomUserAuthenticationProvider">
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:authorization-code />
<oauth:implicit/>
<oauth:refresh-token/>
<oauth:client-credentials />
<oauth:password authentication-manager-ref="userAuthenticationManager"/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="springsec" token-services-ref="tokenServices" />
<!-- <bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" /> -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="300000"></property>
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<mvc:annotation-driven /> <!-- Declares explicit support for annotation-driven MVC controllers #RequestMapping, #Controller -->
<mvc:default-servlet-handler />
<bean id="MyResource" class="demo.oauth2.authentication.resources.MyResource"></bean>
</beans>
You're mixing in several things together. InMemoryTokenStore, JwtTokenStore and JdbcTokenStore are only supposed to be used for different cases. There is no such a thing which of them is safer and which is not.
JwtTokenStore
JwtTokenStore encodes token-related data into the token itself. It does not make tokens persistent and requires JwtAccessTokenConverter as a translator between a JWT-encoded token
and OAuth authentication information. ("Spring Essentials" by Shameer Kunjumohamed, Hamidreza Sattari).
The important thing is that tokens are not persisted at all and validated "on the fly" based on signature.
One disadvantage is that you can't easily revoke an access token, so they normally are granted with short expiry and the revocation is handled at the refresh token. Another disadvantage is that the tokens can get quite large if you are storing a lot of user credential information in them. The JwtTokenStore is not really a "store" in the sense that it doesn't persist any data. read more
InMemoryTokenStore
InMemoryTokenStore stores tokens in server memory so it's hardly possible to share them among different servers. You'll lose all access tokens in InMemoryTokenStore when you restart your authorisation server. I'd prefer to use InMemoryTokenStore only during development and not in a production environment.
The default InMemoryTokenStore is perfectly fine for a single server (i.e. low traffic and no hot swap to a backup server in the case of failure). Most projects can start here, and maybe operate this way in development mode, to make it easy to start a server with no dependencies. read more
JdbcTokenStore
The JdbcTokenStore is the JDBC version of the same thing, which stores token data in a relational database. Use the JDBC version if you can share a database between servers, either scaled up instances of the same server if there is only one, or the Authorization and Resources Servers if there are multiple components. To use the JdbcTokenStore you need "spring-jdbc" on the classpath. read more
In case of JdbcTokenStore you're saving the tokens in real database. So you're safe in case of Authorization service restart. The tokens can be also easily shared among the servers and revoked. But you have more dependancies for database.

CAS with Spring Security - Redirect loop

I've been configuring SSO solution using CAS for existing application with Spring Security integrated. I went through many answers on Stackoverflow but unfortunately anyone could help me. Could you please assist me with this issue from perspective of my configuration? Thank you in advance!
Here is my core security configuration:
<?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:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
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/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<description>This context sets up security configurations of the core module.</description>
<!-- Enabled support for #Secured annotations on Spring bean methods -->
<security:global-method-security secured-annotations="enabled"
access-decision-manager-ref="accessDecisionManager"/>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider"/>
</security:authentication-manager>
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="authenticationUserDetailsService">
<bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<constructor-arg ref="userDetailsService"/>
</bean>
</property>
<property name="serviceProperties" ref="serviceProperties"/>
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://localhost:8443/cas"/>
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>
<security:http entry-point-ref="casEntryPoint">
<security:custom-filter ref="casFilter" position="CAS_FILTER"/>
</security:http>
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://localhost:8443/cas/login"/>
<property name="serviceProperties" ref="serviceProperties"/>
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="casEntryPoint"/>
</bean>
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service" value="http://localhost:8080/myApp/j_spring_cas_security_check"/>
<property name="sendRenew" value="false"/>
</bean>
<!-- Service that retrieves UserDetails from DB for authentication -->
<bean id="userDetailsService" class="com.xxx.yyy.core.security.userdetails.DefaultUserDetailsService">
<property name="pmUserService" ref="pmUserService"/>
</bean>
<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="randomSaltSource">
<property name="userPropertyToUse" value="salt"/>
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<!-- At least one voter must agree that the user can access a resource -->
<bean class="org.springframework.security.access.vote.RoleVoter">
<!-- Override the default is 'ROLE_' prefix for role names -->
<property name="rolePrefix">
<util:constant static-field="com.xxx.yyy.core.security.SecurityConstants.AUTHORITY_PREFIX"/>
</property>
</bean>
</property>
</bean>
...and additional security module:
<?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:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
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/util http://www.springframework.org/schema/util/spring- util-3.0.xsd">
<description>This context sets up security configurations of the web module</description>
<import resource="web-security-urls.xml"/>
<!-- Spring Security Filter Chain -->
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**"
filters="securityContextPersistenceFilter,
logoutFilter,
authenticationFilter,
anonymousAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor"/>
</security:filter-chain-map>
</bean>
<!-- Responsible for propagation of SecurityContext on ThreadLocal from HttpSession -->
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
<!-- define the logout exit point -->
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<!-- go to login page upon successful logout -->
<constructor-arg value="/"/>
<!-- Classes that get run when a user logs out -->
<constructor-arg>
<list>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/j_spring_security_logout"/>
</bean>
<!-- Enable expression evaluation for Spring Security -->
<bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
<bean class="org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator">
<constructor-arg ref="filterSecurityInterceptor"/>
</bean>
And also we have separate module web-security-urls.xml where o.s.s.web.access.intercept.FilterSecurityInterceptor is configured to declare secure URLs
I am not sure if this is the exact problem, but looks like you might be missing a filter url here due to which you are getting a infinite redirect loop.
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
you can add the filter url to filter only a particular url pattern
<property name="filterProcessesUrl" value="/j_spring_cas_security_check"/>
This helped me when i was stuck in the same type of problem.
I dont know if you still have this problem. I was facing the same and it is nerve-wracking. The issue of infinite redirect results when CasAuthenticationFilter is not able to determine if the incoming URL ( redirected URL from CAS server ) needs authentication.
if (!requiresAuthentication(request, response)) {
chain.doFilter(request, response);
return;
}
The requires authentication checks if the request is identified as "filterable" URL.
private static final class FilterProcessUrlRequestMatcher implements RequestMatcher {
private final String filterProcessesUrl;
private FilterProcessUrlRequestMatcher(String filterProcessesUrl) {
Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified");
Assert.isTrue(UrlUtils.isValidRedirectUrl(filterProcessesUrl), filterProcessesUrl + " isn't a valid redirect URL");
this.filterProcessesUrl = filterProcessesUrl;
}
public boolean matches(HttpServletRequest request) {
String uri = request.getRequestURI();
int pathParamIndex = uri.indexOf(';');
if (pathParamIndex > 0) {
// strip everything after the first semi-colon
uri = uri.substring(0, pathParamIndex);
}
if ("".equals(request.getContextPath())) {
return uri.endsWith(filterProcessesUrl);
}
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
}
}
With a context path , the check basically checks if the "service URL" ends with request.getContextPath() + filterProcessesUrl
So, URL in the "service" property of ServiceProperties object needs to match to what is provided in filterProcessesUrl.
For example :
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service"
value="https://localhost:9444/SpringSecurity2.5/tbr/j_spring_cas_security_check" />
<property name="sendRenew" value="false" />
</bean>
<bean id="casFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationSuccessHandler">
<bean
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler" />
</property>
<property name="filterProcessesUrl" value="/tbr/j_spring_cas_security_check"/>
</bean>
Note the matching pattern for /tbr/j_spring_cas_security_check in both these configurations.

How to Skip Spring Login Page

I am using siteminder for authentication but currently for development purpose I am faking the URL attributes like SM_USER through fiddler tool. I am able to get the attribute in my class where I have Implemented my custom methods to get the user Permissions from DB. Everything works fine,at the end it redirects to the Spring Security Login Page.Below is my code snippet...
<http pattern="/pages/UnAuthorized.jsf*" security="none"/>
<http pattern="/pages/Logout.jsf*" security="none"/>
<http pattern="/pages/SessionTimeout.jsf*" security="none"/>
<http auto-config="false" use-expressions="true">
<intercept-url pattern="/**" access="fullyAuthenticated" />
<custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
<logout logout-url="/logout" logout-success-url="/pages/Logout.jsf" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider" >
</authentication-provider>
</authentication-manager>
<bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
<property name="principalRequestHeader" value="SM_USER"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="userDetailsServiceWrapper"
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="UserPermissionsProcessor"/>
</bean>
<bean id="customAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="userDetailsServiceWrapper">
</property>
</bean>
I tried using entry-point-ref as suggested it in one of the post but didn't worked for me.
Is it creating the Authentication Object? If yes set that in SecurityContextHolder as follows.
SecurityContextHolder.getContext().setAuthentication(authentication);
If authentication object is not present, then the below line fails,
and obviously you will be redirected to the login page.

Spring Security with CAS and Forms login

I am writing an application that needs to use CAS authentication for employees, and a username/password form login (which validates against a database table) for customers.
The idea is the front page would have a link to send them to CAS for employees ("click here if you are an employee"), and below that username & password boxes for non-employees.
I have both of these working in separate test apps - based on the sample applications in Spring Security - but am not clear how to combine the two AuthenticationProviders into one.
Current config - mainly from the CAS config with Forms config added:
<?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: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">
<!--Set up the url based security features-->
<security:http entry-point-ref="casEntryPoint" use-expressions="true" >
<security:custom-filter position="FORM_LOGIN_FILTER" ref="casFilter" />
<security:logout logout-success-url="${cas.sso}/logout" />
<security:access-denied-handler ref="accessDeniedHandler" />
<!-- Set up the form login -->
<security:form-login login-page="/login.jsp" authentication-failure- url="/login.jsp?login_error=1"/>
</security:http>
<!-- Specify a destinatation for 403 errors raised by the above URL patterns
this is performed as a 'forward' internally -->
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/error/403.html"/>
</bean>
<!--Hook in the properties for the CAS-->
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<property name="service" value="${cas.service}"/>
<property name="sendRenew" value="true"/>
</bean>
<!--Set up the CAS filter-->
<bean id="casFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureHandler" ref="accessFailureHandler" />
</bean>
<!-- Specify a destinatation for 401 errors raised by casFilter (and UserService) -->
<bean id='accessFailureHandler'
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/error/401.html" />
<property name="useForward" value='true' />
<property name="allowSessionCreation" value="false" />
</bean>
<!--Set up the entry point for CAS-->
<bean id="casEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="${cas.sso}"/>
<property name="serviceProperties" ref="serviceProperties"/>
<property name="encodeServiceUrlWithSessionId" value="false"/>
</bean>
<!--Setup authentication managers-->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider"/>
<security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>
<!-- Our own user details service, which hooks in to the database -->
<bean id='userService' class='test.security.UserDetailsServiceImpl' />
<!-- Enable annotations -->
<security:global-method-security pre-post-annotations="enabled"/>
<!-- Customise an auth provider with the local specifics-->
<bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="userDetailsService" ref="userService"/>
<property name="serviceProperties" ref="serviceProperties"/>
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="${cas.sso}"/>
</bean>
</property>
<property name="key" value="testSSO"/>
</bean>
<!-- Custom auth provider that validates usernames&pwds against DB -->
<bean id="customAuthenticationProvider" class="test.security.CustomAuthenticationProvider" />
</beans>
This gives the error message:
Filter beans '<casFilter>' and '<org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0>' have the same 'order' value.
How can I put both filters into the chain? Or do I need to write my own filter that (somehow?) knows which method is being chosen and then delegates the relevant specific filter?
I am new to Spring Security so is there a better way of doing this entirely?
Thanks!
casFilter must be placed at position=CAS_FILTER

Spring OAuth2 with implicit and password flows

I am trying to setup a project with Spring OAuth 2 using implicit, password and authorization flows.
The problem I have appears when I use the same token endpoint for implicit and the other two, password and authorization needs the basic authentication for client validation while implicit doesn't validate the client secret and I want to use a more clasical login/password authentication for user authorization.
So depending on the configuration one or two flows work.
Having 2 endpoints seems to be the easiest solution, but I can not find how to achieve that.
<?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:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!--
<sec:http pattern="/external/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security" entry-point-ref="authenticationEntryPoint">
<sec:intercept-url pattern="/external/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<sec:anonymous enabled="false" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
-->
<sec:http pattern="/external/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<sec:intercept-url pattern="/external/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<sec:anonymous enabled="false" />
<sec:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="blablabla" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<bean id="tokenStore" class="com.proton.oauthprovider.service.ProtOnTokenStore" />
<bean id="clientDetails" class="com.proton.oauthprovider.service.ProtOnClientDetailsService" />
<bean id="oauthCodeDetails" class="com.proton.oauthprovider.service.ProtOnAuthorizationCodeServices" />
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler" class="com.proton.oauthprovider.service.OAuthUserApprovalHandler">
<property name="autoApproveClients">
<set>
<!-- <value>rest-client</value> -->
</set>
</property>
<property name="tokenServices" ref="tokenServices" />
</bean>
<oauth:authorization-server client-details-service-ref="clientDetails"
token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler" authorization-endpoint-url="/external/oauth/authorize"
user-approval-page="forward:/external/oauth/confirm_access"
error-page="forward:/external/oauth/error"
token-endpoint-url="/external/oauth/token" >
<oauth:authorization-code authorization-code-services-ref="oauthCodeDetails"/>
<oauth:implicit/>
<oauth:refresh-token />
<oauth:password authentication-manager-ref="authenticationManager"/>
</oauth:authorization-server>
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
<!-- Override the default mappings for approval and error pages -->
<bean id="accessConfirmationController" class="com.proton.oauthprovider.controller.AccessConfirmationController">
<property name="clientDetailsService" ref="clientDetails" />
</bean>
</beans>
authenticationEntryPoint is the login form entry point, and the custom classes are more or less the same from sparklr and tonr just using DB backend for storing client and token data.
Ok I got everything wrong, implicit flow does not use token endpoint, it uses authorize one.
So the previous config is ok and I only needed to point implicit flow to /oauth/authorize/ and it works as expected.

Resources