Java 在spring boot中从jwt获取附加属性

Java 在spring boot中从jwt获取附加属性,java,spring,spring-boot,jwt,keycloak,Java,Spring,Spring Boot,Jwt,Keycloak,我正在开发一个spring引导服务,它受Key斗篷保护,并接受jwt承载令牌进行身份验证 我还配置了swagger并将其注册为公共客户端,因此当我从swagger ui发出请求时,KeyClope会生成一个JWT令牌,然后swagger在向api发出请求时使用该令牌进行身份验证 我还为用户信息创建了另外两个私有映射器。现在我想在我的spring控制器中获得这两个属性 下面是我的示例代码。 我对spring安全性和各种处理方法(spring安全性/oauth2/Keyclope等)感到有点迷茫,因

我正在开发一个spring引导服务,它受Key斗篷保护,并接受jwt承载令牌进行身份验证

我还配置了swagger并将其注册为公共客户端,因此当我从swagger ui发出请求时,KeyClope会生成一个JWT令牌,然后swagger在向api发出请求时使用该令牌进行身份验证

我还为用户信息创建了另外两个私有映射器。现在我想在我的spring控制器中获得这两个属性

下面是我的示例代码。
我对spring安全性和各种处理方法(spring安全性/oauth2/Keyclope等)感到有点迷茫,因此非常感谢对解决方案进行一些解释

pom.xml

<!-- spring security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- spring security test -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- KeyCloak -->
        <!-- https://mvnrepository.com/artifact/org.keycloak/keycloak-spring-boot-2-starter -->
        <!-- https://stackoverflow.com/questions/50243088/keycloak-4-0-0-beta-2-with-spring-boot-2 -->      <!---->
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-2-starter</artifactId>
            <version>4.0.0.Final</version>
        </dependency>
控制器示例

    @RequestMapping(value = "HelloWorld1", method = RequestMethod.GET)
    @ApiOperation(value = "HelloWorld1", produces = "application/json")
    @ResponseBody
    public String HelloWorld1(Principal principal) {
//I'd like something like this to work:
//String attr = principal.getAttribute("attribute1");
//
        System.out.println(principal.getName());
        RestTemplate restTemplate = new RestTemplate();
        String text = restTemplate.getForObject(
            "http://localhost:8080/test/test/HelloWorld", String.class);
        return "Hello " + principal.getName() + " " +  "it works! \n " + text;
    }

我不知道KeyClope Spring适配器的具体情况,但您可以使用Spring安全OAuth2的Spring引导模块来实现这一点。在Spring Security DSL中,有一个演示1)如何基于某个JWT声明(或从UserInfo端点检索到的声明)进行授权;2) 如何提取属性以在web控制器、网页等中使用这些属性。请参见此处的“实现客户端”一节

基本上,您需要将此依赖项添加到项目中(Gradle语法,请适应Maven):

然后:

基于OIDC属性/声明的Spring Security DSL(HTTP安全)中的授权
@配置
公共类WebSecurity配置扩展了WebSecurity配置适配器{
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
http.authorizeRequests()
.anyRequest()
.fullyaauthenticated()
.及()
.oauth2Client()
.及()
.oauth2Login()
.userInfoEndpoint()
.userAuthoritiesMapper(userAuthoritiesMapper());
}
私有授权权限映射器userAuthoritiesMapper(){
返回(权限)->{
Set mappedAuthorities=new HashSet();
弗雷奇(
权威->{
if(OidcUserAuthority的权限实例){
OidcUserAuthority OidcUserAuthority=(OidcUserAuthority)权限;
OidcIdToken idToken=oidcUserAuthority.getIdToken();
OidcUserInfo userInfo=oidcUserAuthority.getUserInfo();
列出集团授权=
userInfo.getclairstringlist(“组”).stream()
.map(g->new SimpleGrantedAuthority(“角色”+g.toUpperCase()))
.collect(Collectors.toList());
mappedAuthorities.addAll(组权限);
}
});
返回MappedAuthority;
};
}
}
在web控制器中使用OIDC声明/属性
@GetMapping(“/”)
Mono索引(@AuthenticationPrincipal OAuth2User OAuth2User,模型){
model.addAttribute(“全名”,oauth2User.getName());
model.addAttribute(
“保护者”,
((JSONArray)oauth2User.getAttributes().get(“组”).get(0).equals(“库管理员”));
...    
}

来源:

你能解决你的目的吗?我不明白你的问题。我没有解决我的问题。。。我现在只使用JWT进行身份验证。您是否实现了自定义身份验证管理器?我不确定。。我实现了AuthenticationManagerBuilder,正如您在上面的代码中所看到的
    @RequestMapping(value = "HelloWorld1", method = RequestMethod.GET)
    @ApiOperation(value = "HelloWorld1", produces = "application/json")
    @ResponseBody
    public String HelloWorld1(Principal principal) {
//I'd like something like this to work:
//String attr = principal.getAttribute("attribute1");
//
        System.out.println(principal.getName());
        RestTemplate restTemplate = new RestTemplate();
        String text = restTemplate.getForObject(
            "http://localhost:8080/test/test/HelloWorld", String.class);
        return "Hello " + principal.getName() + " " +  "it works! \n " + text;
    }
implementation('org.springframework.boot:spring-boot-starter-oauth2-client')
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .anyRequest()
        .fullyAuthenticated()
        .and()
        .oauth2Client()
        .and()
        .oauth2Login()
        .userInfoEndpoint()
        .userAuthoritiesMapper(userAuthoritiesMapper());
  }

  private GrantedAuthoritiesMapper userAuthoritiesMapper() {
    return (authorities) -> {
      Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

      authorities.forEach(
          authority -> {
            if (authority instanceof OidcUserAuthority) {
              OidcUserAuthority oidcUserAuthority = (OidcUserAuthority) authority;

              OidcIdToken idToken = oidcUserAuthority.getIdToken();
              OidcUserInfo userInfo = oidcUserAuthority.getUserInfo();

              List<SimpleGrantedAuthority> groupAuthorities =
                  userInfo.getClaimAsStringList("groups").stream()
                      .map(g -> new SimpleGrantedAuthority("ROLE_" + g.toUpperCase()))
                      .collect(Collectors.toList());
              mappedAuthorities.addAll(groupAuthorities);
            }
          });

      return mappedAuthorities;
    };
  }
}
@GetMapping("/")
  Mono<String> index(@AuthenticationPrincipal OAuth2User oauth2User, Model model) {

    model.addAttribute("fullname", oauth2User.getName());
    model.addAttribute(
        "isCurator",
        ((JSONArray) oauth2User.getAttributes().get("groups")).get(0).equals("library_curator"));
    ...    
}