0

I have a controller for users that contains

@PostMapping("/user/register")
public String register  ( @RequestParam String name
                        , @RequestParam String password
                        , @RequestParam String email
                        , HttpServletRequest request)

@GetMapping("/user/confirm/{token}")
public Optional<User> confirm(@PathVariable(value = "token") String token)

and

    @PostMapping("/user/login")
public ResponseEntity<String> login 
                            ( @RequestParam String email
                            , @RequestParam String password
                            , HttpServletRequest request
                            ){
    //System.out.println("post:/user/login email="+email);
    User user = userService.login(email, password);
    if (user==null)
        return ResponseEntity.notFound().build();
    
    HttpSession session = request.getSession(true); // createSession=true
    session.setAttribute(SESSION_USER, user);
    
    **cfgSecurity.setAthenticated(session, user);**
    
    return ResponseEntity.ok("OK");
}

Users have a role that is an enum. The question is how to configure security. Here is my configuration class:

@Configuration
@EnableWebSecurity
public class CfgSecurity extends WebSecurityConfigurerAdapter{

    private static final String PRINCIPAL  = "admin";
    private static final String CREDENTIAL = "password";
    @Autowired AuthenticationManager authenticationManager;
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { // authentication
        auth
          .inMemoryAuthentication()
          .withUser(PRINCIPAL).password(passwordEncoder().encode(CREDENTIAL))
          .roles(roles());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception { // resource security
        http.cors().and().csrf().disable()
            .httpBasic()
            /*
            .and().authorizeRequests()
                .antMatchers("/user/register").permitAll()//.hasRole("ADMIN")
                .antMatchers("/user/confirm/**").permitAll()
                .anyRequest().permitAll()
                
            //.and().formLogin().loginPage("/user/login").permitAll()
             */
          ;
    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception
    {
        //https://www.programcreek.com/java-api-examples/docs/?api=org.springframework.security.authentication.AuthenticationManager
        return super.authenticationManagerBean();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
    private static String[] roles() {
        String[] array = new String[Role.values().length];
        for (Role role : Role.values()) {
            array[role.ordinal()] = role.name();
        }
        return array;
    }

    public void setAthenticated(HttpSession session, User user) {
        //https://stackoverflow.com/questions/4664893/how-to-manually-set-an-authenticated-user-in-spring-security-springmvc
        try {
            Authentication authRequest = new UsernamePasswordAuthenticationToken
                        (PRINCIPAL, passwordEncoder().encode(CREDENTIAL)
                        , user.getAuthorities()
                        );
            Authentication authentication = authenticationManager.authenticate(authRequest);
            
            SecurityContext securityContext = SecurityContextHolder.getContext();
            securityContext.setAuthentication(authentication);
            session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
        }
        catch(Exception ex) {
            System.err.println(ex.toString());
        }
    }
}

It does not work : I get org.springframework.security.authentication.BadCredentialsException: Bad credentials.

Here is User.getAuthorities (referenced in setAuthenticated) :

@Override public Collection<? extends GrantedAuthority> getAuthorities() {

final SimpleGrantedAuthority simpleGrantedAuthority = 
        new SimpleGrantedAuthority(role.toString());
return Collections.singletonList(simpleGrantedAuthority);

}

0

1 Answer 1

0

Here is the way it works: use the encrypted password for AuthenticationManagerBuilder but pass it unencrypted to UsernamePasswordAuthenticationToken.

public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
    auth.inMemoryAuthentication()
        .withUser(PRINCIPAL).password(passwordEncoder().encode(CREDENTIAL))
        .roles(roles());
}

public void setAthenticated(HttpSession session, User user) {
    Authentication authRequest = new UsernamePasswordAuthenticationToken
                        (PRINCIPAL, CREDENTIAL, user.getAuthorities());
    Authentication authentication = authenticationManager
                                      .authenticate(authRequest);
            
    SecurityContext securityContext = SecurityContextHolder.getContext();
    securityContext.setAuthentication(authentication);
    session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.