I want to get current logged in user id and pass it to the view. Users login with username and password.
spring-security.xml
<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.xsd">
<!-- enable use-expressions -->
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/panel/**"
access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login login-page="/login" login-processing-url="/j_spring_security_check"
authentication-failure-url="/login?error" username-parameter="username"
password-parameter="password" authentication-success-handler-ref="authSuccessHandler" />
<logout logout-url="/j_spring_security_logout" logout-success-url="/" />
<!-- enable csrf protection -->
<csrf />
</http>
<beans:bean id="authSuccessHandler" class="com.terafast.tem.AuthSuccessHandler" />
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,password,enabled from users where username=?"
authorities-by-username-query="select u1.username, u2.role from users u1, user_roles u2 where u1.role_id = u2.role_id and u1.username =?" />
</authentication-provider>
</authentication-manager>
</beans:beans>
Controller
#RequestMapping(value = "/request/create", method = RequestMethod.GET)
public String displayVacationRequestPage(Model model) {
Vacation vacation = new Vacation();
model.addAttribute("vacation", vacation);
return "panel/createRequest";
}
Could someone explain how can I do that?
You can add a simply mapping method
#RequestMapping("/user")
public Principal user(Principal user) {
return user;
}
If the /user mapping is reachable it will return the currently authenticated user. Consider annotating your response with #ResponseBody, depending on how you have set up your controller and how you plan to use it in your view.
For passing a particular property you can do something like
#RequestMapping(value="/username", method = RequestMethod.GET)
public String printUser(ModelMap model, Principal user) {
String name = user.getName(); //get logged in username
model.addAttribute("username", name);
return "panel/createRequest";
}
Related
I am using Spring-Security 4 XML configuration to successfully implement password authentication in a spring-mvc webapp.
The problem I have is that when CredentialsExpiredException is thrown by DaoAuthenticationProvider, the system redirects to login-form, instead of reset password.
My context-security xml configuration is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<b:bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<b:constructor-arg value="/index/form" />
</b:bean>
<http auto-config="true" use-expressions="true" disable-url-rewriting="true" entry-point-ref="authenticationEntryPoint" >
<intercept-url pattern="/" access="permitAll" requires-channel="https"/>
<intercept-url pattern="/index" access="permitAll" requires-channel="https"/>
<intercept-url pattern="/index/*" access="permitAll" requires-channel="https"/>
<intercept-url pattern="/**" access="hasAnyRole('USER','SYS_ADMIN' )" requires-channel="https"/>
<form-login
login-page="/index/form"
default-target-url="/dashboard"
login-processing-url="/index"
username-parameter="username"
password-parameter="password"
authentication-failure-handler-ref="exceptionTranslationFilter"
always-use-default-target="true"/>
<logout logout-url="/logout" logout-success-url="/index/logout"/>
<session-management>
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
</http>
<!-- password expiry functionality starts -->
<b:bean id="exceptionTranslationFilter" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<b:property name="exceptionMappings">
<b:props>
<b:prop key="org.springframework.security.authentication.CredentialsExpiredException">/resetpassword</b:prop>
</b:props>
</b:property>
<b:property name="defaultFailureUrl" value="/index/error"/>
</b:bean>
<b:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<b:constructor-arg name="providers">
<b:list>
<b:ref bean="daoAuthenticationProvider"/>
</b:list>
</b:constructor-arg>
</b:bean>
<b:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider ">
<b:property name="userDetailsService" ref="customUserDetailsService" />
<b:property name="passwordEncoder" ref="passwordEncoder" />
</b:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService" />
<authentication-provider ref="daoAuthenticationProvider" />
</authentication-manager>
<b:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" >
</b:bean>
Given the above configuration, when I enter correct username and password of user whose credentials have expired, I get redirected to url = "/index/form"
I have ran the debugger (I'm using Eclipse), and the code execution is as follows (all classes belong to Spring Security 4):
AbstractUserDetailsAuthenticationProvider.authenticate() throws CredentialsExpiredException when executing postAuthenticationChecks.check(user);
ExceptionMappingAuthenticationFailureHandler.onAuthenticationFailure() gets the url to be /resetpassword before calling getRedirectStrategy().sendRedirect(request, response, url);
DefaultRedirectStrategy.sendRedirect() gets the redirect url to be "/myapp/resetpassword"
The problem occurs on LoginUrlAuthenticationEntryPoint.commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException).
Because useForward is set to false, it calls redirectUrl = buildRedirectUrlToLoginPage(request, response, authException);
redirectUrl ends up being "/index/form".
Even if I set useForward to true and subclass LoginUrlAuthenticationEntryPoint in order to override determineUrlToUseForThisRequest the AuthenticationException I get is of type InsufficientAuthenticationException.
The interesting thing is that the url on my browser is https://localhost:8443/myapp/resetpassword, but what it displays is the login form.
Have you encountered this problem before? If so, how did you get spring to redirect to reset password?
Most of the configuration I obtained from https://stackoverflow.com/a/14383194/158499
Thanks in advance, Lucas
<intercept-url pattern="/**" access="hasAnyRole('USER','SYS_ADMIN' )" requires-channel="https"/>
when redirect to /resetpassword will redirect to login page. Please allow this url to access without authentication.
<intercept-url pattern="/resetpassword" access="permitAll" requires-channel="https"/>
How to disable CSRF in Spring Security 4 only for specific URL pattern through XML configuration?
Spring-security.xml
<security:http auto-config="true" use-expressions="true" pattern="/ext/**">
<csrf disabled="true" />
</security:http>
<security:http auto-config="true" use-expressions="true" authentication-manager-ref="authenticationManager">
<security:intercept-url pattern="/auth/**" access="hasAnyRole('ROLE_USER')" />
<security:form-login login-page="/login" authentication-success-handler-ref="loginSuccessHandler" authentication-failure-url="/login" login-processing-url="/j_spring_security_check" />
<security:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler" />
</security:http>
My code works fine if I use only one security:http block, but after I add another block it throws error as below:
Error
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter gov.in.controller.filter.LoginAdtAuthFailHdlr.usernamePasswordAuthenticationFilter; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter] is defined: expected single matching bean but found 2: org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#1
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 58 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter] is defined: expected single matching bean but found 2: org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#1
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 60 more
Could not achieve with just XML changes. Below worked for me
Change in Spring-security.xml
<security:http use-expressions="true" authentication-manager-ref="authenticationManager">
<security:intercept-url pattern="/auth/**" access="hasAnyRole('ROLE_USER')" />
<security:form-login login-page="/login" authentication-success-handler-ref="loginSuccessHandler" authentication-failure-url="/login" login-processing-url="/j_spring_security_check" />
<security:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler" />
<security:csrf request-matcher-ref="csrfSecurityRequestMatcher" />
</security:http>
CsrfSecurityRequestMatcher
public class CsrfSecurityRequestMatcher implements RequestMatcher {
private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
private RegexRequestMatcher unprotectedMatcher = new RegexRequestMatcher("/ext/**", null);
#Override
public boolean matches(HttpServletRequest request) {
if(allowedMethods.matcher(request.getMethod()).matches()){
return false;
}
return !unprotectedMatcher.matches(request);
}
}
You can have two (or more) filter chains:
<http pattern="/your-specific/**">
<!-- ... -->
<csrf disabled="true"/>
</http>
<http>
<!-- ... -->
</http>
I am using spring-security with a Spring-MVC application. Currently I am able to login user, password hashing and all is working beautifully. Whenever I need the authenticated person object, I retrieve the name via Spring security, then by accessing database I get the user object. All good till there. Now when I load the application first time, I log in, I close the tab, and I again give the application address, I would like to check if the user is authenticated and redirect. This is where I am having problem. I went through many tutorials on net, and I am almost doing the same. Kindly have a look at what I am doing wrong. Thank you for your time.
Controller :
#RequestMapping(value = "/", method = RequestMethod.GET)
public String listPersons(Model model) {
boolean id = isAuthenticated(); // Here I am calling the function I have written to see if I am logged in
if(id){
return "redirect:/canvas/list";
} else {
model.addAttribute("person", new Person());
model.addAttribute("listPersons", this.personService.listPersons());
model.addAttribute("notices",new Notes());
model.addAttribute("canvases",new Canvas());
return "person";
}
}
isAuthenticatedFunction :
private boolean isAuthenticated(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication == null){ return false;}
if(authentication instanceof AnonymousAuthenticationToken) {
return false;
} else {
return true;
}
}
Security-application-context.xml
<import resource="servlet-context.xml" />
<!-- Global Security settings -->
<security:global-method-security pre-post-annotations="enabled" />
<security:http pattern="/" security="none" />
<security:http create-session="ifRequired" use-expressions="true" auto-config="false" disable-url-rewriting="true">
<security:form-login login-page="/" default-target-url="/canvas/list" always-use-default-target="false" authentication-failure-url="/login?error" />
<security:remember-me key="_spring_security_remember_me" user-service-ref="userDetailsService" token-validity-seconds="1209600" data-source-ref="dataSource"/>
<security:intercept-url pattern="/canvas/list" access="hasRole('ROLE_USER')" />
<security:logout logout-success-url="/" delete-cookies="JSESSIONID" invalidate-session="true" logout-url="/j_spring_security_logout" />
<security:port-mappings>
<security:port-mapping http="80" https="443"/>
</security:port-mappings>
<security:session-management session-fixation-protection="newSession" invalid-session-url="/invalidSession.html">
<security:concurrency-control max-sessions="3" error-if-maximum-exceeded="true" expired-url="/sessionExpired.html"/>
</security:session-management>
</security:http>
<!-- queries to be run on data -->
<beans:bean id="rememberMeAuthenticationProvider" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<beans:property name="key" value="_spring_security_remember_me" />
<beans:property name="tokenRepository" ref="jdbcTokenRepository"/>
<beans:property name="userDetailsService" ref="LoginServiceImpl"/>
</beans:bean>
<!--Database management for remember-me -->
<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>
To retrieve logged in user, I am using the method mentioned below, which works like a charm right now.
#Override
public Person getCurrentlyAuthenticatedUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication == null){
System.out.println("User is not authenticated");
return null;
} else {
Person person = personDAO.findPersonByUsername(authentication.getName());
return person;
}
}
We have spring security oauth2 based application. Every thing is working fine. But i am failed to change default token endpoint from "/oauth/token" to "/external/oauth/token".
My spring-servlet.xml
<http pattern="/external/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
use-expressions="true" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/external/oauth/token" access="isFullyAuthenticated()" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<oauth:authorization-server client-details-service-ref="clientDetails"
token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler" token-endpoint-url="/external/oauth/token">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
But the result when i access this endpoint is
{
error: "unauthorized"
error_description: "An Authentication object was not found in the SecurityContext"
}
am i missing any thing ? Please suggest.
With the version 2.0.5.RELEASE or above of spring-security-oauth2
In one line in java based configuration, tested and works fine, somehow it's overriding the RequestMapping value of the TokenEndpoint class.
#Configuration
#EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.pathMapping("/oauth/token", "<your custom endpoint>")
}
}
Just struggled with this for a few days, but have it working now on latest Spring Oauth2 1.0.5.RELEASE. I'm not 100% sure my solution is the classiest (Step 4 in particular), but it works and I'm able to move forward.
In my case, I wanted to remove the /oauth prefix from the urls to end up with just /token and /authorize. The solution for me was mostly xml config, with two hacks to override endpoint request mappings.
1 - In app context xml, add authorization-endpoint-url and token-endpoint-url attribs to your <oauth:authorization-server> element.
Mine:
<oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" authorization-endpoint-url="/authorize" token-endpoint-url="/token">
2 - In app context xml, adjust the security endpoints accordingly. There should be two, which respectively manage security on the token and auth urls. Need to update the pattern prop on <http> and <intercept-url> tags.
Mine:
<http pattern="/token/**" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/token/**" access="IS_AUTHENTICATED_FULLY" />
...
<http pattern="/authorize/**" access-denied-page="/login.jsp?authorization_error=true" disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/authorize/**" access="IS_AUTHENTICATED_FULLY" />
3 - (If you chose to employ the optional clientCreds filter.) In app context xml, you should already have wired-in the clientCredentialsTokenEndpointFilter bean as a <custom-filter> within yourelement. So, within the filter's bean, add afilterProcessesUrl` property.
Mine:
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
<property name="filterProcessesUrl" value="/token" />
</bean>
4 - The last step is to override the request mapping urls of the actual internal endpoint controllers. The spring oauth2 lib comes with two classes: AuthorizationEndpoint and TokenEndpoint. Each use #RequestMapping type annotations to bind the url (as we all do for our projects' app controllers). For me, it was a hair-pulling effort to attempt to override the value of the request mappings in any way other than to (sadly) recreate the spring class package in my src folder, copy the AuthorizationEndpoint and TokenEndpoint classes verbatim into said folder, and edit the inline #RequestMapping annotation values.
Anyway, that does the trick. Would love to hear of a more graceful way to override the endpoint controller request mapping values.
Thanks.
Final, working app context:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:sec="http://www.springframework.org/schema/security" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
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
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd
"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<!-- Declare OAuth2 services white-list. (This is the top of the config.) -->
<oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" authorization-endpoint-url="/authorize" token-endpoint-url="/token">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<!-- <oauth:password /> -->
</oauth:authorization-server>
<bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<!-- This bean bridges client auth service and user tokens... kind of an out of place requirement. -->
<property name="tokenServices" ref="tokenServices" />
</bean>
<!-- This starts the far back-end config for client token management. -->
<sec:authentication-manager id="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetailsService" />
</bean>
<bean id="clientDetailsService" class="com.mycompany.oauth.spring.security.oauth2.IntegratedOauth2ClientDetailsService">
<!-- This bean is what wires OAuth2 into the persistence stack for client details stored in the oauth_client table. -->
</bean>
<!-- OAuth is layered on to spring security which is centered around users which requires a user auth manager. -->
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="daoAuthenticationProvider" />
</authentication-manager>
<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
</bean>
<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="clientDetailsService" />
</bean>
<bean id="tokenStore" class="com.mycompany.oauth.spring.security.oauth2.IntegratedOAuth2TokenStore">
<!-- This bean is what wires OAuth2 tokens into my company's application stack. -->
<constructor-arg ref="dataSource" />
</bean>
<!-- **************************************************************************************** -->
<!-- Finally, sew OAuth into spring security with some http tags... -->
<!-- **************************************************************************************** -->
<!-- The OAuth2 endpoint for direct token requests (i.e. for client_credentials flow). -->
<http pattern="/token/**" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/token/**" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
<property name="filterProcessesUrl" value="/token" />
</bean>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="myrealm" />
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<!-- The OAuth2 endpoint for user-approved authorization (i.e. for "authorization" flow involving user login/approve). -->
<http pattern="/authorize/**" access-denied-page="/login.jsp?authorization_error=true" disable-url-rewriting="true" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/authorize/**" access="IS_AUTHENTICATED_FULLY" />
<form-login authentication-failure-url="/login.jsp?authentication_error=true" default-target-url="http://www.mycompany.com/" login-page="/login.jsp" login-processing-url="/login.do" />
<http-basic />
<anonymous />
</http>
</beans>
For customize the token end point URL, do the following steps.
1) Write your own class that extends ClientCredentialsTokenEndpointFilter class & call ClientCredentialsTokenEndpointFilter class constructor with "/external/oauth/token" value.
super("/external/oauth/token");
2) Plug your new customize filter in security configuration.
Replace
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
with
<custom-filter ref="your customize filter" after="BASIC_AUTH_FILTER" />
3) Create your own class for new mapping (/external/oauth/token) & extend tokenendpoint.
4) Change http & intercept-url element's pattern attribute value to "/external/oauth/token"
You are making this harder than what it should be, it's actually very simple !
(Notice I'm using "oauth2:" instead of "oauth:" as the XML tag)
Go to your security-context.xml
Find "oauth2:authorization-server" in the above file.
<oauth2:authorization-server
client-details-service-ref="someService"
request-validator-ref="someScopeRequestValidator"
token-services-ref="someTokenServices" >
Just add token-endpoint-url="/oauth/whatever_you_like"
<oauth2:authorization-server
client-details-service-ref="someService"
request-validator-ref="someScopeRequestValidator"
token-services-ref="someTokenServices"
**token-endpoint-url="/oauth/whatever_you_like"** >
I have these rules to access pages in my app:
<http auto-config="true" use-expressions="true">
<!-- NON AUTHENTICATION PAGES -->
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/about" access="permitAll" />
<!-- LOGIN FILTER -->
<intercept-url pattern="/login" access="!isAuthenticated()" />
<intercept-url pattern="/j_spring_security_check" access="!isAuthenticated()" />
<intercept-url pattern="/logout" access="!isAuthenticated()" />
<!-- RESOURCES AND OTHER URLs FILTER -->
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
<!-- FORM LOGIN -->
<form-login login-page="/login" default-target-url="/upload" authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" />
</http>
and what I need is to redirect to some url (e.g. /access-denied) when access fails and handle this event in controller.
#RequestMapping(value = "/access-denied", method = RequestMethod.GET)
public String accessDenied(Model model, RedirectAttributes ra) {
// do what I want
return "redirect:login";
}
For example user enters /upload and he is not logged in so it will be redirected to /access-denied.
It might help to explain why you need to do the redirect yourself, since Spring Security will do this automatically. When access is denied, the default behaviour for an unauthenticated user, is to redirect them to the login page (which seems to be what you want to do).
If you want to customize the process, the strategy used is the AuthenticationEntryPoint it would probably make more sense to implement this than to use a controller. I've written more about this in a previous answer.
If you just want to slot in some extra functionality, you can extend LoginUrlAuthenticationEntryPoint and override the commence method, calling the superclass to do the redirect.
Note that this means the login-page value from the namespace element won't be used. You'll need to set the login URL in the constructor for LoginUrlAuthenticationEntryPoint.
Notice the access-denied-page attribute in security-http in code that follows.
<security:global-method-security
pre-post-annotations="enabled" />
<security:http auto-config="false" use-expressions="true"
disable-url-rewriting="true" entry-point-ref="loginUrlAuthenticationEntryPoint"
access-denied-page="/access-denied">
<security:intercept-url pattern="/someurl"
access="isAuthenticated()" />
</security:http>