春季如何使用jwt进行授权?

时间:2020-02-16 14:05:41

标签: spring-security jwt

下面是一个示例,我使用jwt实现了授权,添加了我的用户,但是授权期间出现问题,授权没有发生,邮件在我的项目中将始终是唯一的,我该怎么办?在这种情况下,是否使用相同的UsernamePasswordAuthenticationToken方法?

@RestController
@RequestMapping(value = "/api/v1/auth/")

public class AuthenticationRestControllerV1 {
private final AuthenticationManager authenticationManager;

private final JwtTokenProvider jwtTokenProvider;

private final UserService userService;

@Autowired
public AuthenticationRestControllerV1(AuthenticationManager authenticationManager, JwtTokenProvider jwtTokenProvider, UserService userService) {
    this.authenticationManager = authenticationManager;
    this.jwtTokenProvider = jwtTokenProvider;
    this.userService = userService;
}

@PostMapping("/login")
public ResponseEntity login(@RequestBody AuthenticationRequestDto requestDto) {
    System.out.println(requestDto.getUsername());
    System.out.println(requestDto.getPassword());
    try {
        String username = requestDto.getUsername();
        authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, requestDto.getPassword()));
        User user = userService.findByUsername(username);

        if (user == null) {
            throw new UsernameNotFoundException("User with username: " + username + " not found");
        }

        String token = jwtTokenProvider.createToken(username, user.getRoles());

        Map<Object, Object> response = new HashMap<>();
        response.put("username", username);
        response.put("token", token);

        return ResponseEntity.ok(response);
    } catch (AuthenticationException e) {
        throw new BadCredentialsException("Invalid username or password");
    }
}

}

此刻出现问题authenticationManager.authenticate(新的UsernamePasswordAuthenticationToken(用户名,requestDto.getPassword()));

public class JwtConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

private JwtTokenProvider jwtTokenProvider;

public JwtConfigurer(JwtTokenProvider jwtTokenProvider) {
    this.jwtTokenProvider = jwtTokenProvider;
}

@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
    JwtTokenFilter jwtTokenFilter = new JwtTokenFilter(jwtTokenProvider);
    httpSecurity.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}



public class JwtTokenFilter extends GenericFilterBean {
@Autowired
private JwtTokenProvider jwtTokenProvider;

public JwtTokenFilter(JwtTokenProvider jwtTokenProvider) {
    this.jwtTokenProvider = jwtTokenProvider;
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
        throws IOException, ServletException {

    String token = jwtTokenProvider.resolveToken((HttpServletRequest) req);
    if (token != null && jwtTokenProvider.validateToken(token)) {
        Authentication auth = jwtTokenProvider.getAuthentication(token);

        if (auth != null) {
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
    }
    filterChain.doFilter(req, res);
}

}


@Component
public class JwtTokenProvider {

@Value("${jwt.token.secret}")
private String secret;
@Value("${jwt.token.expired}")
private long validityInMilliseconds;

@Autowired
private UserDetailsService userDetailsService;

@Bean
public BCryptPasswordEncoder passwordEncoder() {
    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    return bCryptPasswordEncoder;
}

@PostConstruct
protected void init() {
    secret = Base64.getEncoder().encodeToString(secret.getBytes());
}

public String createToken(String username, Set<Role> roles) {

    Claims claims = Jwts.claims().setSubject(username);
    claims.put("roles", getRolesName(roles));

    Date now = new Date();
    Date validity = new Date(now.getTime() + validityInMilliseconds);

    return Jwts.builder()//
            .setClaims(claims)//
            .setIssuedAt(now)//
            .setExpiration(validity)//
            .signWith(SignatureAlgorithm.HS256, secret)//
            .compact();
}


/*
Метод возвращает аутентификацию по токену
 */
public Authentication getAuthentication(String token) {
    UserDetails userDetails = this.userDetailsService.loadUserByUsername(getUsername(token));
    return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}

public String getUsername(String token) {
    return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}

public String resolveToken(HttpServletRequest req) {
    String bearerToken = req.getHeader("Authorization");
    if (bearerToken != null && bearerToken.startsWith("Bearer_")) {
        return bearerToken.substring(7, bearerToken.length());
    }
    return null;
}

public boolean validateToken(String token) {
    try {
        Jws<Claims> claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);

        if (claims.getBody().getExpiration().before(new Date())) {
            return false;
        }

        return true;
    } catch (JwtException | IllegalArgumentException e) {
        throw new JwtAuthenticationException("JWT token is expired or invalid");
    }
}

private List<String> getRolesName(Set<Role> roles) {
    List<String> result = new ArrayList<>();
    roles.forEach(role -> {
        result.add(role.name());
    });

    return result;
}

}


public class JwtUser implements UserDetails {
private final Integer id;
private final String username;
private final String surname;
private final String patronymic;
private final String email;
private final String password;
private final Date birthDay;
private final Boolean active;
private final String mobileNumber;
private final Collection<? extends GrantedAuthority> authorities;
private final String activationCode;

public JwtUser(Integer id,
               String username,
               String surname,
               String patronymic,
               String email,
               String password,
               Date birthDay,
               Boolean active,
               String mobileNumber,
               Collection<? extends GrantedAuthority> authorities,
               String activationCode) {
    this.id = id;
    this.username = username;
    this.surname = surname;
    this.patronymic = patronymic;
    this.email = email;
    this.password = password;
    this.birthDay = birthDay;
    this.active = active;
    this.mobileNumber = mobileNumber;
    this.authorities = authorities;
    this.activationCode = activationCode;
}

public final class JwtUserFactory {
public JwtUserFactory() {
}

public static JwtUser create(User user) {
    return new JwtUser(
            user.getId(),
            user.getUsername(),
            user.getSurname(),
            user.getPatronymic(),
            user.getEmail(),
            user.getPassword(),
            user.getBirthDay(),
            user.getActive(),
            user.getMobileNumber(),
            mapToGA(user.getRoles()),
            user.getActivationCode()
    );
}

public static Set<GrantedAuthority> mapToGA(Set<Role> roles) {
    return roles.stream().map(role ->
            new SimpleGrantedAuthority(role.name())).
            collect(Collectors.toSet());
}
}


@Service
public class JwtUserDetailsService implements UserDetailsService {

@Autowired
private UserService userService;



@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userService.findByUsername(username);
    if (user == null) {
        throw new UsernameNotFoundException("User with this username" + username + " not found");
    }
    JwtUser jwtUser = JwtUserFactory.create(user);
    return jwtUser;
}
}

授权不起作用。我在行org.springframework.security.authentication.BadCredentialsException: Invalid username or password中收到错误authenticationManager.authenticate (new UsernamePasswordAuthenticationToken (username, requestDto.getPassword ())) ;。正如我在本案例中所指出的,这是唯一的邮件,如何使用她的授权?要改变什么?

这是调试org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4138b2c7时跟踪的内容:主体:xxx@gmail.com;凭证:[受保护];已验证:假;详细信息:null;没有授予任何权限

public enum Role implements GrantedAuthority {
ADMIN,
USER,
WATCHER;
public static Role lookup(String name) {
    for (Role role : Role.values()) {
        if (role.name().equals(name)) {
            return role;
        }
    }
throw new IllegalArgumentException("No matching constant for " + Role.class.getSimpleName() + " name = " + name);

}

@Override
public String getAuthority() {
    return null;
}

}

0 个答案:

没有答案