springboot安全性-总是获取错误的凭据

e37o9pze  于 2021-06-20  发布在  Mysql
关注(0)|答案(0)|浏览(124)

我已经调试了10个小时,似乎不明白为什么在springsecurity中不断出现错误的凭证。
实际上,我可以看到我正在从数据库中抓取用户 userdetailsservice . 密码匹配正确(目前没有散列/编码任何内容),但是当我深入到框架中时,我得到了mismatch creds异常。
我真的没有主意了,我觉得我已经把这个代码重写了3-4次了,但都没有用。
我在打 /login 生成令牌。

jwt安全配置

import com.schachte.asciiphile.security.messaging.JwtAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
@Order(1)
public class JwtSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String ROOT_CTX_MATCH_PATH = "/phile/**";

    @Autowired
    private JwtAuthenticationEntryPoint entryPoint;

    @Qualifier("userDetailsServiceImpl")
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(new JwtLoginFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
        http.headers().cacheControl();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }
}

jwt登录筛选器

import com.fasterxml.jackson.databind.ObjectMapper;
import com.schachte.asciiphile.model.JwtAuthententicationToken;
import com.schachte.asciiphile.model.User;
import com.schachte.asciiphile.security.util.JwtGenerator;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.auth0.jwt.JWT;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import static com.auth0.jwt.algorithms.Algorithm.HMAC512;
import java.io.IOException;
import java.util.Date;
import java.util.List;

public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter {

    private JwtGenerator jwtGenerator = new JwtGenerator();

    private AuthenticationManager authenticationManager;

    public JwtLoginFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(
            HttpServletRequest req, HttpServletResponse res)
            throws AuthenticationException {

        User creds = null;
        try {
            creds = new ObjectMapper()
                    .readValue(req.getInputStream(), User.class);
        } catch (IOException e) {
            e.printStackTrace();
        }

        List<GrantedAuthority> grantedAuthorities = AuthorityUtils
                .commaSeparatedStringToAuthorityList(creds.getRole());

        return authenticationManager.authenticate(
                new JwtAuthententicationToken(
                        creds.getUsername(),
                        creds.getPassword(),
                        grantedAuthorities
                )
        );
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, auth);
        String token = JWT.create()
                .withSubject(((User) auth.getPrincipal()).getUsername())
                .withExpiresAt(new Date(System.currentTimeMillis() + 864_000_000))
                .sign(HMAC512("secret".getBytes()));
        response.addHeader("Authorization", "Token " + token);
    }
}

jwt身份验证令牌

import lombok.Data;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;

import java.util.List;

@Data
public class JwtAuthententicationToken extends UsernamePasswordAuthenticationToken {

    private String username;
    private String password;
    private List<GrantedAuthority> grantedAuthorities;

    public JwtAuthententicationToken(String username, String password, List<GrantedAuthority> grantedAuthorities) {
        super(null, null);
        this.username = username;
        this.password = password;
        this.grantedAuthorities = grantedAuthorities;
    }

    @Override
    public Object getCredentials() {
        return null;
    }

    @Override
    public Object getPrincipal() {
        return this.username;
    }
}

自定义用户详细信息

import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

public class CustomUserDetails extends User implements UserDetails {
  private Collection<? extends GrantedAuthority> authorities;

  public CustomUserDetails(final User user, Collection<? extends GrantedAuthority> authorities) {
    super(user);
    this.authorities = authorities;
  }

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

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

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

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

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

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

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

用户

import javax.persistence.*;
import lombok.Data;

@Entity
@Data
public class User {

  public User() {}

  public User(String username, String pass, String role) {
    this.username = username;
    this.password = pass;
    this.role = role;
  }

  public User(User username) {
    this.email = username.getEmail();
    this.password = username.getPassword();
    this.premium = username.getPremium();
    this.storedBytes = username.getStoredBytes();
    this.username = username.getUsername();
  }

  @Id
  @Column(name = "username")
  private String username;

  @Column(name = "password")
  private String password;

  @Column(name = "email")
  private String email;

  @Column(name = "premium")
  private int premium;

  @Column(name = "storedbytes")
  private int storedBytes;

  @Column(name = "role")
  private String role;
}

用户详细信息服务

import com.schachte.asciiphile.model.CustomUserDetails;
import com.schachte.asciiphile.model.User;
import com.schachte.asciiphile.repository.UserRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepo applicationUserRepository;

    public UserDetailsServiceImpl(UserRepo applicationUserRepository) {
        this.applicationUserRepository = applicationUserRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<User> applicationUser = applicationUserRepository.findByUsername(username);
        if (!applicationUser.isPresent()) {
            throw new UsernameNotFoundException(username);
        }
        return new CustomUserDetails(applicationUser.get(), AuthorityUtils
                .commaSeparatedStringToAuthorityList(applicationUser.get().getRole()));
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题