OAuth2密码模式

OAuth2密码模式

授权模块的改动

首先对 auth-server 进行改造,使之支持 password 模式:

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
            .withClient("admin")
            .secret(new BCryptPasswordEncoder().encode("123"))
            .resourceIds("res1")
            .authorizedGrantTypes("password","refresh_token")
            .scopes("all")
            .redirectUris("http://localhost:8082/02.html");
}

这里其他地方都不变,主要是在 authorizedGrantTypes 中增加了 password 模式。

由于使用了 password 模式之后,用户要进行登录,所以我们需要配置一个 AuthenticationManager,还是在 AuthorizationServer 类中,具体配置如下:

@Autowired
AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints
            .authenticationManager(authenticationManager)
            .tokenServices(tokenServices());
}

那么这个 authenticationManager 实例从哪里来呢?这需要我们在 Spring Security 的配置中提供,这松哥在之前的 Spring Security 系列教程中说过多次,我就不再赘述,这里直接上代码,在 SecurityConfig 中添加如下代码:

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

配置完成后,重启 auth-server。

接下来配置 client-app,首先我们添加登录功能,修改 index.html ,如下:

<body>
你好,江南一点雨!

<form action="/login" method="post">
    <table>
        <tr>
            <td>用户名:</td>
            <td><input name="username"></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input name="password"></td>
        </tr>
        <tr>
            <td><input type="submit" value="登录"></td>
        </tr>
    </table>
</form>
<h1 th:text="${msg}"></h1>
</body>

我们来看登录接口:

package com.example.clientapp.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * @author 朝花不迟暮
 * @version 1.0
 * @date 2020/10/31 17:41
 */
@Controller
public class LoginController
{
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    private static Map<String, Object> resp;

    @Autowired
    RestTemplate restTemplate;

    @PostMapping("/login")
    public String login(String username, String password, Model model)
    {
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("username", username);
        map.add("password", password);
        map.add("client_secret", "123");
        map.add("client_id", "admin");
        map.add("grant_type", "password");
        resp = restTemplate.postForObject("http://localhost:8080/oauth/token", map, Map.class);
        String access_token = (String) resp.get("access_token");
        Integer expires_in = (Integer) resp.get("expires_in");
        log.info("【获取token的过期时间】 expires_in:{}",expires_in);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + access_token);
        HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
        ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8081/admin/hello", HttpMethod.GET, httpEntity, String.class);
        model.addAttribute("msg", entity.getBody());
        return "02.html";
    }

    @RequestMapping("02.html")
    public String loginPage()
    {
        return "02";
    }
}

在登录接口中,当收到一个用户名密码之后,我们通过 RestTemplate 发送一个 POST 请求,注意 post 请求中,grant_type 参数的值为 password,通过这个请求,我们可以获取 auth-server 返回的 access_token,格式如下:

{access_token=02e3a1e1-925f-4d2c-baac-42d76703cae4, token_type=bearer, refresh_token=836d4b75-fe53-4e41-9df1-2aad6dd80a5d, expires_in=7199, scope=all}

我们提取出 access_token 之后,接下来去请求资源服务器,并将访问到的数据放在 model 中。

OK,配置完成后,启动 client-app,访问 http://localhost:8082/02.html 页面进行测试。授权完成后,我们在项目首页可以看到如下内容:
在这里插入图片描述
码云:https://gitee.com/thirtyleo/common-codes.git

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java 实现 OAuth2 密码模式客户端可以使用 Spring Security OAuth2 客户端库。下面是一个简单的示例: 首先,需要在 pom.xml 文件中添加 Spring Security OAuth2 客户端库的依赖: ```xml <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.3.7.RELEASE</version> </dependency> ``` 然后,可以使用以下代码获取访问令牌: ```java import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; // 创建 OAuth2RestTemplate ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails(); resourceDetails.setAccessTokenUri("https://oauth2.example.com/token"); resourceDetails.setClientId("your_client_id"); resourceDetails.setClientSecret("your_client_secret"); resourceDetails.setUsername("your_username"); resourceDetails.setPassword("your_password"); OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails); // 使用 OAuth2RestTemplate 发送请求 String result = restTemplate.getForObject("https://api.example.com/resource", String.class); ``` 在上面的代码中,我们首先创建了一个 ResourceOwnerPasswordResourceDetails 对象,并设置了访问令牌 URI、客户端 ID、客户端密钥、用户名和密码等参数。然后,我们使用这些参数创建了一个 OAuth2RestTemplate 对象,并使用它发送了一个请求。 需要注意的是,使用密码模式获取访问令牌需要在 OAuth2 服务器上启用密码模式,并且客户端需要被授权使用密码模式。另外,密码模式通常不被推荐使用,因为它需要客户端存储用户的用户名和密码,这可能会导致安全风险。建议使用其他授权方式,如授权码模式或隐式授权模式
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值