【问题标题】:Multiple authentification strategies in spring boot securitySpring Boot 安全性中的多种身份验证策略
【发布时间】:2019-04-23 20:34:04
【问题描述】:

为了在 Spring Security 中使用自定义身份验证,您必须实现 UserDetailsService 接口并覆盖 loadUserByUsername 方法,例如下面的示例

public class UserServiceImpl implements UserDetailsService{

    @Autowired
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String useremail)
            throws UsernameNotFoundException {
        Users user = userDao.findByUserEmail(useremail);
        if(user == null){
            throw new UsernameNotFoundException("UserName or Password Invalid.");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.getEnabled(), true, true, true, getGrantedAuthorities(userDao.getUserRole(user.getUsersId())));
    }

它在整个网站上都可以正常工作。

我现在要做的是从同一主机公开一个宁静的 Web 服务,并且对该 WS 的所有请求都将通过 /api/** 使用不同类型的身份验证(例如:使用令牌) 有可能吗?如果是这样,有什么想法吗?任何有用的资源?

【问题讨论】:

    标签: java spring authentication spring-security token


    【解决方案1】:

    你可以先做如下的安全配置类

    @Configuration
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
    private final TokenAuthenticationFilter tokenAuthenticationFilter;
    
    ...
    
    public SecurityConfiguration(TokenAuthenticationFilter tokenAuthenticationFilter) {
        this.corsFilter = corsFilter;
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
            .antMatchers(HttpMethod.OPTIONS, "/**");
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
        .and()
            .addFilterBefore(tokenAuthenticationFilter, TokenAuthenticationFilter.class)
            .exceptionHandling()
            .authenticationEntryPoint(problemSupport)
            .accessDeniedHandler(problemSupport)
        .and()
            .logout()
            .logoutUrl("/api/logout")
            .logoutSuccessHandler(You log out success handler goes here)
            .permitAll()
        .and()
            .authorizeRequests()
            .antMatchers("/api/**").authenticated();
    
    }
    

    }

    您的 TokenAuthenticationFilter 类将为每个请求执行令牌真实性。

    @Configuration
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
    private final TokenAuthenticationFilter tokenAuthenticationFilter;
    
    ...
    
    public SecurityConfiguration(TokenAuthenticationFilter tokenAuthenticationFilter) {
        this.corsFilter = corsFilter;
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
            .antMatchers(HttpMethod.OPTIONS, "/**");
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
        .and()
            .addFilterBefore(tokenAuthenticationFilter, TokenAuthenticationFilter.class)
            .exceptionHandling()
            .authenticationEntryPoint(problemSupport)
            .accessDeniedHandler(problemSupport)
        .and()
            .logout()
            .logoutUrl("/api/logout")
            .logoutSuccessHandler(You log out success handler goes here)
            .permitAll()
        .and()
            .authorizeRequests()
            .antMatchers("/api/**").authenticated();
    
       }
     }
    

    【讨论】:

    • 我明白你想说什么,但这并不能解决问题,在这种情况下,所有的请求都会通过 TokenAuthenticationFilter。但我想要的是将此令牌身份验证仅应用于 url 模式 /api/** ,并为其他请求应用另一个身份验证(电子邮件、密码)
    • 所以在这种情况下,这个答案可能会解决你的问题stackoverflow.com/a/46239996/4801359
    猜你喜欢
    • 1970-01-01
    • 2019-02-07
    • 2015-04-10
    • 2019-02-21
    • 2019-03-13
    • 2014-07-06
    • 2020-02-09
    • 2020-10-21
    • 1970-01-01
    相关资源
    最近更新 更多