了解jwt和登录逻辑

时间:2018-02-19 00:55:25

标签: java spring-security jwt

我是jwt的新手,我正在使用网上的一些资源来帮助我正确理解jwt,我现在能够生成令牌并访问需要授权的资源,首先,我有一个像

@RequestMapping("/token")
public class TokenController {
    private JwtGenerator jwtGenerator;
    public TokenController(JwtGenerator jwtGenerator) {
        this.jwtGenerator = jwtGenerator;
    }

    @PostMapping
    public String generate(@RequestBody final JwtUser jwtUser) {

        return jwtGenerator.generate(jwtUser);
    }

对不起,我将发布大量代码。我正在使用邮递员进行测试 所以当我把它作为帖子传递时

{
"useNe" : "ter",
"paord":"123",
"role":"ain"
} or 
{
"username" : "ter",
"is":"123",
"role":"admin"
}

我正在生成一个令牌,它应该需要一个用户名和密码我认为应该生成一个jwt令牌,我想实现一个正确的登录,下面是安全配置和我有的其他类

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationProvider authenticationProvider;

    @Autowired
    private JwtAuthenticationEntryPoint entryPoint;

    @Bean
    public AuthenticationManager authenticationManagerBean() {
        return new ProviderManager(Collections.singletonList(authenticationProvider));
    }

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilter() throws Exception {
        JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
        filter.setAuthenticationManager(authenticationManager());
        // we set success handler so that we overide the default redirection
        filter.setAuthenticationSuccessHandler(new JwtSuccessHandler());
        return filter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .authorizeRequests().antMatchers("**/rest/**").authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint(entryPoint)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        http.headers().cacheControl();

    }
}

我如何创建一个会生成令牌的登录,或者不是jwt的标准,我也希望有两种类型的角色用户和管理员,管理员可以访问所有资源,而用户可以访问一些,这里是其他课程

public class JwtAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {


    public JwtAuthenticationTokenFilter() {
        super("/rest/**");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest,
                                                HttpServletResponse httpServletResponse)
            throws AuthenticationException, IOException, ServletException {

        String header = httpServletRequest.getHeader("Authorisation");

        if (header == null || !header.startsWith("Token")) {
            throw new RuntimeException("JWT Token is missing");
        }

        String authenticationToken  = header.substring(6);

        JwtAuthenticationToken token = new JwtAuthenticationToken(authenticationToken);

       return  getAuthenticationManager().authenticate(token);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authResult);
        chain.doFilter(request, response);
    }

}

我的jwt生成器应该不需要用户名和密码进行登录     @零件     公共类JwtGenerator {

    public String generate(JwtUser jwtUser) {

        Claims claims = Jwts.claims()
                .setSubject(jwtUser.getUserName());
        claims.put("userId", String.valueOf(jwtUser.getId()));
        claims.put("role", jwtUser.getRole());

        return Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, "youtube")
                .compact();
    }
}
@Component
public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    @Autowired
    private JwtValidator validator;


    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken)
            throws AuthenticationException {

    }

    @Override
    protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken)
        throws AuthenticationException {

        JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) usernamePasswordAuthenticationToken;
        String token = jwtAuthenticationToken.getToken();

        JwtUser jwtUser = validator.validate(token);
        if(jwtUser == null){
           throw   new  RuntimeException("user token is incorrect" );
        }

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

        //we return an authenticated user
        return new JwtUserDetails(jwtUser.getUserName(),jwtUser.getId(),token , grantedAuthorities);
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return (JwtAuthenticationToken.class.isAssignableFrom(aClass));
    }
}

我如何改进这一点并最终获得生成jwt的正确登录并将其保存在每个请求的标题中

0 个答案:

没有答案