获取经过身份验证的用

时间:2017-05-24 15:54:15

标签: java spring security spring-boot oauth

我使用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()

提前致谢。

2 个答案:

答案 0 :(得分:0)

实施自定义身份验证提供程序并将您的用户详细信息存储为Principal

Spring Security Authentication Provider

答案 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!");
    }

感谢您的所有努力。