Springboot 整合Spring Security Oauth2.0自定义登录接口

前面几篇文章用Springboot依次整合了Spring Security、Oauth2.0、JWT、向令牌添加额外信息,本篇文章主要记录使用自定义登录接口
Springboot整合Spring Security Oauth2.0 + JWT (一)
Springboot整合Spring Security Oauth2.0 + JWT (二)
Springboot整合Spring Security Oauth2.0 + JWT (三)
Springboot整合Spring Security Oauth2.0 + JWT (四)

application.yml配置客户端信息与认证服务器的信息

security:
  oauth2:
    client:
      access-token-uri: http://localhost:${server.port}/oauth/token
      user-authorization-uri: http://$localhost}:${server.port}/oauth/authorize
      client-id: client
      client-secret: secret

这里的客户端信息要是认证服务器那边配置在内存或存储在数据库的对应的信息

找一个配置类注入RestTemplate
Springboot 整合Spring Security Oauth2.0自定义登录接口_第1张图片
自定义LoginController

@RestController
@RequestMapping("/api/auth")
public class LoginController {

    @Value("${security.oauth2.client.access-token-uri}")
    private String accessTokenUri;

    @Value("${security.oauth2.client.client-id}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;

    @Autowired
    private RestTemplate restTemplate;


    @PostMapping("/login")
    public ResultModel login(@RequestBody Map<String,String> loginParams,@RequestHeader HttpHeaders httpHeaders) throws UnsupportedEncodingException {
        // 构造 post的body内容(要post的内容,按需定义)
        MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
        paramsMap.set("grant_type", "password");
        String username = loginParams.get("username");
        paramsMap.set("username", username);
        String password = loginParams.get("password");
        paramsMap.set("client_id", clientId);
        paramsMap.set("client_secret", clientSecret);
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            paramsMap.set("password", new String(decoder.decodeBuffer(password)));
        } catch (IOException e) {
            return ResultModel.fail("密码有误");
        }
        // 使用客户端的请求头,发起请求
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // 强制移除 原来的请求头,防止token失效
        httpHeaders.remove(HttpHeaders.AUTHORIZATION);
        //构造请求实体和头
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity(paramsMap, httpHeaders);
        JSONObject authInfo = null;
        try {
            authInfo = restTemplate.postForObject(accessTokenUri, request, JSONObject.class);
        } catch (HttpClientErrorException e) {
            if (e.getStatusCode().equals(HttpStatus.BAD_REQUEST)) {
                byte[] bs = e.getResponseBodyAsByteArray();
                String msg = new String(bs, "utf-8");
                Map<String, String> mm = (Map<String, String>) JSON.parse(msg);
                return ResultModel.fail(mm.get("error_description"));
            } else {
                return ResultModel.fail("登录失败");
            }
        }
        JSONObject jsonObject = new JSONObject(authInfo);
        String jwt = jsonObject.getString("access_token");
        Map<String, String> jwtMap = new HashMap<>();
        jwtMap.put("jwt", jwt);
        return ResultModel.success(jwtMap);
    }
}

WebSecurity配置登录接口绕过鉴权,资源服务器登录接口放行
在这里插入图片描述

测试登录接口,使用base64传递密码
Springboot 整合Spring Security Oauth2.0自定义登录接口_第2张图片
这个demo是一个boot工程,基于前面四篇文章,认证服务器、资源服务器都放在一个工程里面的,可以实现简单的前后端分离项目的登录授权。
源代码(包括之前四篇文章)在
基于springboot,sprint security,oauth2,jwt实现rbac权限模型与单点登录

你可能感兴趣的:(Spring,Security,Spring,Boot,jwt,spring,boot,java)