【问题标题】:How to configure SpringBoot authentication for RestController如何为 RestController 配置 SpringBoot 认证
【发布时间】:2021-12-09 08:33:23
【问题描述】:

我有一个用户控制器包含

@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)

    @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");
}

用户的角色是一个枚举。 问题是如何配置安全性。 这是我的配置类:

@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());
        }
    }
}

它不起作用:我明白了 org.springframework.security.authentication.BadCredentialsException:错误的凭据。

这里是 User.getAuthorities(在 setAuthenticated 中引用):

@覆盖 公共收藏 getAuthorities() {

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

}

【问题讨论】:

    标签: java spring-boot security authentication spring-restcontroller


    【解决方案1】:

    这是它的工作方式:使用 AuthenticationManagerBuilder 的加密密码,但将其未加密传递给 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-16
      • 2016-07-26
      • 2019-03-25
      • 1970-01-01
      • 2020-05-26
      • 2021-09-12
      • 2014-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多