当前位置: 首页 > 知识库问答 >
问题:

Spring Security性和API令牌身份验证

端木明贤
2023-03-14

我一直在网上搜索使用Spring实现基于令牌的身份验证的许多不同方法

我想要的是将用户名/密码传递给SS的内置机制,并在成功后生成一个令牌,我将其传回给用户。然后用户在自定义标头中使用令牌发出所有未来的请求。令牌将在一定时间后过期。我知道这是Oauth所做的,但还是不要使用它。

所以我找到了一些有用的东西。我可以使用用户名/密码登录并取回令牌。然后,我可以成功地使用令牌发出请求。当局不起作用的东西。这是我正在做的。。。

  • 自定义身份验证失败处理程序,它简单地返回HttpServletACK。SC_UNAUTHORIZED
  • 自定义成功处理程序,简单地返回HttpServletACK。SC_OK和令牌
  • 自定义身份验证入口点,只需使用HttpServletACK进行响应。SC_UNAUTHORIZED

现在,我还有一个自定义的UserDetails和UserDetails服务。

public class MyUserDetails implements UserDetails {

    private User user; // this is my own User object
    private List<GrantedAuthority> authorities;

    public MyUserDetails(User user, List<GrantedAuthority> authorities) {
        this.user = user;
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public void setAuthorities(List<GrantedAuthority> authorities) {
        this.authorities = authorities;
    }
}

@Service
public class MyUserDetailsService implements UserDetailsService {

    private final UserService userService;

    @Autowired
    public MyUserDetailsService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }

        List<GrantedAuthority> authorities = new ArrayList<>();
        // for now, just add something
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));

        return new MyUserDetails(user, authorities);
    }
}

为了在标题中查找令牌并告诉spring一切正常,我创建了一个AuthTokenFilter。。。

public class AuthTokenFilter extends UsernamePasswordAuthenticationFilter {

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String authToken = httpRequest.getHeader("X-TOKEN-AUTH");
        String username = null;
        if (authToken != null) {
            username = Jwts.parser()
                    .setSigningKey("1234")
                    .parseClaimsJws(authToken)
                    .getBody()
                    .getSubject();


        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            // TODO: validate token
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
            SecurityContextHolder.getContext().setAuthentication(authentication);

        }

        chain.doFilter(request, response);

    }
}

这就是我配置Web安全的方式:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Autowired
    private RestAuthEntryPoint authenticationEntryPoint;

    @Autowired
    private AuthSuccessHandler authSuccessHandler;

    @Autowired
    private AuthFailureHandler authFailureHandler;


    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(new ShaPasswordEncoder());

        return authenticationProvider;
    }

    @Bean
    public AuthTokenFilter authenticationTokenFilterBean() throws Exception {
        AuthTokenFilter authenticationTokenFilter = new AuthTokenFilter();
        authenticationTokenFilter.setAuthenticationManager(authenticationManagerBean());
        return authenticationTokenFilter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authenticationProvider(authenticationProvider())
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .and()
                .formLogin()
                .permitAll()
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(authSuccessHandler)
                .failureHandler(authFailureHandler)
                .and()
                .logout()
                .permitAll()
                .and()
                .sessionManagement()
                .maximumSessions(1);

        http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

        http.authorizeRequests().anyRequest().authenticated();
    }


}

一切似乎都可以接受SS根本没有限制访问。如果令牌在那里,SS只是让一切通过。

共有1个答案

易扬
2023-03-14

嗯,经过多次尝试和错误后,只需将以下内容添加到我的SpringSecurityConfig

@EnableGlobalMethodSecurity(securedEnabled=true,preprestenabled=true)

有点惊讶我没有早点遇到这个。不确定这是不是有点新鲜。

 类似资料:
  • 我刚刚开始在.NET中开发我的第一个REST API。由于它将是无状态的,我将使用令牌进行身份验证: 基本思想(System.Security.Cryptography): null 检查凭据是否有效(用户名,将哈希密码与db值进行比较) 如果为真,则加密数据对象 对生成的令牌使用HMAC,并将其存储到数据库 将令牌(不带HMAC)返回给用户(cookie/字符串) 对需要身份验证的方法的请求:

  • null 我的自定义rest筛选器: 上面的内容实际上会导致应用程序启动时出现一个错误:有人能告诉我如何最好地执行此操作吗?pre_auth筛选器是执行此操作的最好方法吗? 编辑 使用Spring-security实现解决方案 希望它能帮助其他人…

  • 我有一个LaravelAPI(实际上是LumenAPI)服务于VueJS前端。Vue应用程序允许用户登录到谷歌。然后将Google令牌发送回Lumen API,后者使用Google验证令牌,然后验证电子邮件地址是否为有效用户。然后它生成一个令牌,与用户一起存储在数据库中,并返回用户对象。 我没有使用Passport或jwt auth之类的东西。那么现在,我如何使用默认的Auth中间件来验证(现在已

  • 很好的一天, 我正在使用asp.netapi和Angular。 当我试图从api获取身份验证令牌时,我收到错误 我有一个控制器,它为我的应用程序返回身份验证令牌。这是控制器的逻辑 如你所见,我正在返回对象LoginAprovado。 我不知道如何解决这个问题,它似乎是一个cors问题。 这是我的网页配置 请注意,在我的customeheaders部分中,access controol allow

  • 我正在尝试在Dropwizard web应用程序中实现OAuth2身份验证。我已经创建了所需的<code>验证器 我所需的行为是,在我的客户端通过在我的登录页面上提供他/她的凭据登录后,我想将客户端重定向到我使用Dropwizard Views创建的问候语页面,并且路径为“/me”,如下所示: 我的问候资源如下所示: 目前,我得到一个“访问此资源需要凭据。”登录后的响应。在阅读了一些关于令牌认证的