SpringSecurity - Custom Authentication

This is my scenario:

  • The web application performs SSO sorting for many applications.
  • registered user, than clicking on the link, and the application makes a message with user information (name, pwd [useless], role) to the corresponding application
  • I am embedding SpringSecurity in one of these applications to take advantage of its privileges (session privileges, methods provided by its classes, etc.).

So, I need to develop a custom filter - I think - it can extract user information from the request, extract from the database through the user DetailUserService , then user information (email address, etc.), and then authenticate this user in accordance with the role obtained from the request.

I watched Pre-Authentication , but I'm not sure if this is the right choice. It seems that this object is expected to be used when the director is already in the session established by some previous validation mechanism (right?).

I think that after determining the right filter, I will need to do something like:

GrantedAuthority[] ga= new GrantedAuthority[1]; ga[0] = new GrantedAuthorityImpl(myUser.getRole()); SecurityContext sc = SecurityContextHolder.getContext(); Authentication a = new UsernamePasswordAuthenticationToken(userName, userPwd, ga); a = authenticationManager.authenticate(a); sc.setAuthentication(a); 

Is this the right direction to solve my problem? Do you have any suggestions to help me find what is missing?

Thanks everyone

Luke

Addition:

Hello Sirks! Sorry to bother you again, but it seems that translating your code according to SpringSecurity 2.0.4 is harder than I thought: S Problem in XML ... I tried a different configuration, but I always worked in namespace problems, missing attributes , etc.

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" 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-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> <security:http> <security:intercept-url pattern="/**" access="isAuthenticated()" /> <security:logout logout-url="/logout" logout-success-url="http://milan-ias-vs.usersad.everis.int/DMTest/" invalidate-session="true" /> <security:custom-filter position="PRE_AUTH_FILTER" ref="preAuthenticatedProcessingFilter" /> </security:http> <bean id="preAuthenticatedProcessingFilter" class="it.novartis.ram.authentication.PreAuthenticatedProcessingFilter"> <custom-filter position="PRE_AUTH_FILTER"/> <property name="authenticationManager" ref="authenticationManager" /> </bean> <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> <property name="preAuthenticatedUserDetailsService"> <bean class="it.novartis.ram.authentication.PreAuthenticatedUserDetailsService" /> </property> </bean> <security:authentication-manager alias="authenticationManager"> <security:authentication-provider ref="preauthAuthProvider" /> </security:authentication-manager> </beans> 

The 2 lines that refer to the CUSTOM-FILTER element are two different attempts, both of which are signed as an error. How can I specify the position of my filter as a property?

Also, the link to the authentication provider when defining the authorization manager is marked as an error. I think I need to also specify it as a property, right?

I hope you can give me one last push;) Thanks again,

Luke

+6
source share
2 answers

Yes, pre-authentication scenarios are exactly what you are looking for.

It seems that this object is supposed to be used when the main one is already in the session established by some previous validation mechanism (right?).

In fact, you cannot use Pre-Authentication to create the PreAuthenticatedAuthenticationToken from the request as you wish. Just do a few things that I described in another question .

First print AbstractPreAuthenticatedProcessingFilter to get the username and role from the request:

 public class MyPreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter { public MyPreAuthenticatedProcessingFilter( AuthenticationManager authenticationManager) { setAuthenticationDetailsSource(new MyAuthenticationDetailsSource()); } @Override protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { return "Anonymous"; } @Override protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { return "N/A"; } public static class MyAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, MySessionUserDetails> { // roles probably should be encrypted somehow static final String ROLES_PARAMETER = "pre_auth_roles"; @Override public MySessionUserDetails buildDetails(HttpServletRequest req) { // create container for pre-auth data return new MySessionUserDetails(req.getParameter(ROLES_PARAMETER)); } } } 

MySessionUserDetails class will split spring into roles in a SimpleGrantedAuthority list or any other GrantedAuthority implementation. Additionally, the list is recommended and is superior to GrantedAuthority[] .

Second, introduce the AuthenticationUserDetailsService :

 public class MyPreAuthenticatedUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> { @Override public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws UsernameNotFoundException { MySessionUserDetails sessionUserDetails = (MySessionUserDetails) token.getDetails(); List<GrantedAuthority> authorities = sessionUserDetails.getAuthorities(); return new User(token.getName(), "N/A", true, true, true, true, authorities); } } 

Then in your XML join blocks together:

 <security:http use-expressions="true"> <security:intercept-url pattern="/**" access="isAuthenticated()" /> <security:custom-filter position="PRE_AUTH_FILTER" ref="myPreAuthenticationFilter" /> </security:http> <bean id="myPreAuthenticationFilter" class="com.example.MyPreAuthenticatedProcessingFilter"> <property name="authenticationManager" ref="authenticationManager" /> </bean> <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> <property name="preAuthenticatedUserDetailsService"> <bean class="com.example.MyPreAuthenticatedUserDetailsService" /> </property> </bean> <security:authentication-manager alias="authenticationManager"> <security:authentication-provider ref="preauthAuthProvider" /> </security:authentication-manager> 

And voila! You had to authenticate User to use in your application.

The code I wrote here requires spring Security 3.1, which I highly recommend if you intend to use it (it requrire spring 3.0.7+). In addition, Spring Security Guide is your friend!

+12
source

For completeness, in Spring Security 4 things are slightly modified. For example, using the Java configuration is highly recommended. Thus, it is easier to integrate with Spring Boot.

This follows the Java configuration, which is equivalent to the XML configuration specified in the answers above.

 @Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(customAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class) .authenticationProvider(preauthAuthProvider()) .authorizeRequests() .anyRequest().authenticated(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(preauthAuthProvider()); } @Bean public PreAuthenticatedAuthenticationProvider preauthAuthProvider() { PreAuthenticatedAuthenticationProvider preauthAuthProvider = new PreAuthenticatedAuthenticationProvider(); preauthAuthProvider.setPreAuthenticatedUserDetailsService( userDetailsServiceWrapper()); return preauthAuthProvider; } @Bean public OnlyRolesPreAuthenticatedUserDetailsService userDetailsServiceWrapper() { OnlyRolesPreAuthenticatedUserDetailsService service = new MyPreAuthenticatedUserDetailsService(); return service; } @Bean public MyPreAuthenticatedProcessingFilter customAuthFilter() throws Exception { MyPreAuthenticatedProcessingFilter filter = new MyPreAuthenticatedProcessingFilter(); filter.setAuthenticationManager(authenticationManager()); return filter; } } 

I think the above code is worth it, because the examples on the Internet are very simple, and the Spring documentation has no such details.

+10
source

Source: https://habr.com/ru/post/925666/


All Articles