我使用Spring security oauth2实现一个项目,一切都运行得很好,现在我想开始深入挖掘基础知识。我想检查发出请求的用户是否是资源的实际用户所有者,最终结果将是例如:
/ private / users / {uuid} / clients返回指定用户的所有客户端。
所以我的控制器现在看起来像这样:
@RestController
public class HomeController {
@Autowired
private UserService userService;
@GetMapping(value = "/")
public String index() {
return "Hello world";
}
@GetMapping(value = "/private")
public String privateTest(Principal principal) {
User user = userService.get(principal.getName());
return user.getUuid();
}
}
编辑:完整的安全代码(正常工作)以获得更好的解释。
ResourceServerConfig
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable().and()
.authorizeRequests()
.antMatchers("/","/home","/register","/login").permitAll()
.antMatchers("/private/**").authenticated();
}
}
CustomUserDetails ,其中包含getter和setter
public class CustomUserDetails implements UserDetails {
private Collection<? extends GrantedAuthority> authorities;
private String password;
private String username;
private String uuid;
public CustomUserDetails(User user) {
this.username = user.getUsername();
this.password = user.getPassword();
this.uuid = user.getUuid();
this.authorities = translate(user.getRoles());
}
}
AuthorizationServerConfig
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("my-trusted-client")
.authorizedGrantTypes("client_credentials", "password")
.authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT").scopes("read","write","trust")
.resourceIds("oauth2-resource").accessTokenValiditySeconds(5000).secret("secret");
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()");
}
}
主要
@SpringBootApplication
public class DummyOauthApplication {
@Autowired
private PasswordEncoder passwordEncoder;
public static void main(String[] args) {
SpringApplication.run(DummyOauthApplication.class, args);
}
@Autowired
public void authenticationManager(AuthenticationManagerBuilder builder, UserRepository repository, UserService service) throws Exception {
//Setup a default user if db is empty
if (repository.count() == 0) {
service.save(new User("user", "password", UUID.randomUUID().toString(), Arrays.asList(new Role("USER"), new Role("ACTUATOR"))));
}
builder.userDetailsService(userDetailsService(repository)).passwordEncoder(passwordEncoder);
}
private UserDetailsService userDetailsService(final UserRepository repository) {
return username -> new CustomUserDetails(repository.findByUsername(username));
}
}
所以,使用我实施的方式。我可以获得实际用户,但每次调用端点时都会隐含数据库查询。获取用户并与用户uuid匹配。
我想找到另一种方法,我可以让用户然后比较uuid = user.getUuid()
提前致谢。
答案 0 :(得分:0)
实施自定义身份验证提供程序并将您的用户详细信息存储为Principal
答案 1 :(得分:0)
经过一段时间和很多错误,我设法找到了一个我离开这里的解决方案。可以在问题中看到CustomUserDetails,从那里你可以轻松获得uuid并与所请求的匹配。
public static CustomUserDetails getCurrentUser() {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
if (authentication != null) {
if (authentication.getPrincipal() instanceof CustomUserDetails) {
return (CustomUserDetails) authentication.getPrincipal();
}
}
throw new IllegalStateException("User not found!");
}
编辑:如果您想要返回用户,请执行此类操作
public class CustomUserDetails implements UserDetails {
private Collection<? extends GrantedAuthority> authorities;
private String password;
private String username;
private User user;
public CustomUserDetails(User user) {
this.username = user.getUsername();
this.password = user.getPassword();
this.user = user;
this.authorities = translate(user.getRoles());
}
}
然后在Utils或其他东西中,
public static User getCurrentUser() {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
if (authentication != null) {
if (authentication.getPrincipal() instanceof CustomUserDetails) {
CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
return userDetails.getUser();
}
}
throw new IllegalStateException("User not found!");
}
感谢您的所有努力。