【问题标题】:How to get all attributes from java.security.Principal?如何从 java.security.Principal 获取所有属性?
【发布时间】:2020-02-16 05:10:03
【问题描述】:

我学习 Spring 安全性并使用 Spring Security 5OAuth2 Login 编写简单的 Web 应用程序。我想从Principal(电子邮件、用户名等)获取信息,但我找不到任何方法。写一些JSON-parser 不是一个好主意,因为我很确定有一些方法可以获取用户帐户详细信息。

配置

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and().oauth2Login();
    }
}

控制器

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.security.Principal;

@Controller
public class HomeController {

    @GetMapping({"", "/"})
    @ResponseBody
    public Principal getHome(Principal principal) {
        return principal;
    }

}

Application.yml

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: xyz1
            client-secret: secret1
          facebook:
            client-id: xyz2
            client-secret: secret2
          github:
            client-id: xyz3
            client-secret: secret3

【问题讨论】:

    标签: spring spring-boot spring-security oauth-2.0


    【解决方案1】:

    创建一个新对象,表示您希望从源返回的数据子集, 即,这些细节的来源有多个值,因此使用一些列表或集合或映射来存储该数据并表示它, 正如您提到的,您正在使用 OAuth2:

     @RequestMapping("/user")
        public Authentication user(OAuth2Authentication authentication) {
            LinkedHashMap<String, Object> details = (LinkedHashMap<String, Object>) authentication.getUserAuthentication().getDetails();
            return details.get("email");
        }
    

    【讨论】:

    • 1. details.get - 返回类型是对象,而不是身份验证 2。如果我将方法返回类型更改为对象并运行应用程序,我会收到错误:当前用户主体不是类型 [org.springframework.security.oauth2.provider.OAuth2Authentication]跨度>
    【解决方案2】:

    通过反复试验,在 Spring Boot 2.3.2 中,我发现在那个特定场景(带有 Spring Boot 的 OAuth2)中,您必须在 onAuthenticationSuccess 方法上转换获得的 Authentication 对象(是的,这就是我的场景,因为我在身份验证成功处理程序中观察到了这个对象 - 但这个场景会有很大不同吗?)到OAuth2AuthenticationToken。如果您真的暂停执行并将 Authentication 对象添加到 Watches,您会发现它确实是那种类型。现在这个对象的 getPrincipal() 返回正确的转换 OAuth2User 对象,它有一个方法 getAttributes()。我真的希望更容易弄清楚。

    事实上,在我的场景中,OAuth2User 对象可以直接传递给我的 Controller 方法(我不确定该注释 @AuthenticationPrincipal 是否必要或正确..):

    @Controller
    @RequestMapping("/authorized")
    public class AuthorizedController {
    
        @RequestMapping("/default")
        public String handle(@AuthenticationPrincipal OAuth2User principal,
                Model m) {
             // ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      相关资源
      最近更新 更多