0
点赞
收藏
分享

微信扫一扫

Spring Security和JWT实现登录认证

JWT是一种用于身份验证和授权的开放标准,它可以在客户端和服务器之间安全地传输信息

前言:

在使用JWT进行身份验证时,用户在登录成功后会收到一个包含JWT的令牌,该令牌会存储在客户端(例如浏览器的Cookie或本地存储)中。 客户端在每次请求时都会携带该JWT令牌,服务器通过验证该令牌来确认用户的身份和权限 如何实现登录认证 登录成功通过JWT生成一串字符串作为Token,返回给前端 前端每次请求的时候都在请求头中携带上这个Token 后端每次都使用JWT对该Token进行校验,以此来判断用户是否登录 实现步骤

配置Spring Security:

创建一个配置类,继承自WebSecurityConfigurerAdapter,并添加@Configuration和@EnableWebSecurity注解。 在配置类中,重写configure(HttpSecurity http)方法 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { /** * 自定义用户认证逻辑 */ @Autowired private UserDetailsService userDetailsService;

/**
 * 认证失败处理类
 */
@Autowired
private AuthenticationEntryPointImpl unauthorizedHandler;
// 配置登录认证的URL、身份验证逻辑和访问权限
// ...

} @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity // CSRF禁用,因为不使用session .csrf().disable() // 认证失败处理类 .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() // 基于token,所以不需要session .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() 用户登录:

创建一个认证控制器,用于处理用户登录请求。 在认证控制器中,注入AuthenticationManager和JwtTokenUtil,用于进行身份验证和生成JWT令牌 @RestController public class AuthController { @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtTokenUtil jwtTokenUtil; @Autowired private UserService userService;

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
    // 验证用户身份信息
    Authentication authentication = authenticationManager.authenticate(
        new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
    SecurityContextHolder.getContext().setAuthentication(authentication);

    // 生成JWT令牌
    UserDetails userDetails = userService.loadUserByUsername(loginRequest.getUsername());
    String token = jwtTokenUtil.generateToken(userDetails);

    // 返回JWT令牌给客户端
    return ResponseEntity.ok(new JwtResponse(token));
}

} JWT令牌生成和验证:

创建一个JWT工具类,用于生成和验证JWT令牌。 在JWT工具类中,设置JWT令牌的有效期等 public class JwtTokenUtils { private static final String EMPLOYEE_ID_KEY = ""; private static final String STUDENT_ID_KEY = ""; private static final String TOKEN_TYPE_KEY = "*";; private static final String SECRE_DEVICE_KEY = "secretdeviceheliplay!";

/**
 * 生成Token
 * @param employeeId   用户标识(唯一)
 * @return
 */
public static String createToken(Long employeeId, String tokenType, String scope) {
    Algorithm algorithm = Algorithm.HMAC256(SECRE_KEY);
    Date expireTime = new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME);
    String token = JWT.create()
            .withIssuer(ISSUSER)
            .withIssuedAt(new Date())
            .withExpiresAt(expireTime)
            .withClaim(EMPLOYEE_ID_KEY, employeeId)
            .withClaim(TOKEN_TYPE_KEY, tokenType)
            .withClaim(SCOPE_KEY, scope)
            .sign(algorithm);
    return token;
}

/**
 * 生成Token
 * @param employeeId   用户标识(唯一)
 * @return
 */
public static String createDeviceToken(Long studentId, String tokenType, String scope) {
    Algorithm algorithm = Algorithm.HMAC256(SECRE_DEVICE_KEY);
    Date expireTime = new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME);
    String token = JWT.create()
            .withIssuer(ISSUSER)
            .withIssuedAt(new Date())
            .withExpiresAt(expireTime)
            .withClaim(STUDENT_ID_KEY, studentId)
            .withClaim(TOKEN_TYPE_KEY, tokenType)
            .withClaim(SCOPE_KEY, scope)
            .sign(algorithm);
    return token;
}

} 授权访问控制:

在Spring Security的配置类中,根据JWT令牌中的用户身份和权限信息,进行访问控制的配置。 可以使用hasRole、hasAnyRole、hasAuthority @Service("ss") public class PermissionService { /** 所有权限标识 / private static final String ALL_PERMISSION = "::";

/** 管理员角色权限标识 */
private static final String SUPER_ADMIN = "admin";

private static final String ROLE_DELIMETER = ",";

private static final String PERMISSION_DELIMETER = ",";

/**
 * 验证用户是否具备某权限
 * 
 * @param permission 权限字符串
 * @return 用户是否具备某权限
 */
public boolean hasPermi(String permission)
{
    if (StringUtils.isEmpty(permission))
    {
        return false;
    }
    LoginUser loginUser = SecurityUtils.getLoginUser();
    if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
    {
        return false;
    }
    return hasPermissions(loginUser.getPermissions(), permission);
}

/**
 * 验证用户是否不具备某权限,与 hasPermi逻辑相反
 *
 * @param permission 权限字符串
 * @return 用户是否不具备某权限
 */
public boolean lacksPermi(String permission)
{
    return hasPermi(permission) != true;
}

/**
 * 验证用户是否具有以下任意一个权限
 *
 * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
 * @return 用户是否具有以下任意一个权限
 */
public boolean hasAnyPermi(String permissions)
{
    if (StringUtils.isEmpty(permissions))
    {
        return false;
    }
    LoginUser loginUser = SecurityUtils.getLoginUser();
    if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
    {
        return false;
    }
    Set<String> authorities = loginUser.getPermissions();
    for (String permission : permissions.split(PERMISSION_DELIMETER))
    {
        if (permission != null && hasPermissions(authorities, permission))
        {
            return true;
        }
    }
    return false;
}

... }

结论 通过以上配置,我们可以利用Spring Security和JWT实现登录认证。每次登录都会生成不同的token值,每次访问接口都需要携带token验证,保证了数据的安全性 结尾语 以上代码只是部分示例,请根据实际情况调整

举报

相关推荐

0 条评论