Spring Boot OAuth2

来源:互联网 发布:魅族清除数据锁屏密码 编辑:程序博客网 时间:2024/06/05 22:59

最近在项目中使用了OAuth2做鉴权服务,将主要步骤整理一下:
使用Spring Cloud OAuth2起步依赖会比较简单,在pom.xml中添加依赖

<dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-oauth2</artifactId></dependency> //父项目中使用了cloud版本 Brixton.SR5<dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-dependencies</artifactId>            <version>Brixton.SR5</version>            <type>pom</type>            <scope>import</scope>        </dependency>    </dependencies></dependencyManagement>

加入Spring Cloud OAuth2后会包含Spring-Security,Spring-Security-OAuth2等依赖.
OAuth2两部分AuthorizationServer和ResourceServer,使用注解@EnableAuthorizationServer的类实现AuthorizationServerConfigurer(一般AuthorizationServerConfigurerAdapter)接口,就可以对授权服务进行配置.
主要配置三个部分,ClientDetailsServiceConfigurer客户端连接详情,grant_type,scopes等,AuthorizationServerSecurityConfigurer,访问token接口的安全限制,如tokenKeyAccess,checkTokenAccess,AuthorizatinoServerEndpointsConfigurer,授权和token的服务,如authenticationManager,passwordEncode,userDetailsService.

@Configuration@EnableAuthorizationServerprotected static class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {    private TokenStore tokenStore = new InMemoryTokenStore();    @Autowired    @Qualifier("authenticationManagerBean")    private AuthenticationManager authenticationManager;    @Autowired    private AuthUserDetailsService userDetailsService;    @Override    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {        clients.inMemory()               .withClient("browser")               .authorizedGrantTypes("refresh_token", "password")               .scopes("ui");    }    @Override    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {        endpoints                .tokenStore(tokenStore)                .authenticationManager(authenticationManager)                .userDetailsService(userDetailsService);    }    @Override    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {        oauthServer                .tokenKeyAccess("permitAll()")                .checkTokenAccess("isAuthenticated()");    }}

配置WebSecurityConfig,是token服务能够访问.

@Configuration@EnableWebSecurityprotected static class webSecurityConfig extends WebSecurityConfigurerAdapter {    @Autowired    private AuthUserDetailsService userDetailsService;    @Override    protected void configure(HttpSecurity http) throws Exception {        http            .authorizeRequests().anyRequest().authenticated()        .and()            .csrf().disable();    }    @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {        auth.userDetailsService(userDetailsService)                .passwordEncoder(new BCryptPasswordEncoder());    }    @Override    @Bean    public AuthenticationManager authenticationManagerBean() throws Exception {        return super.authenticationManagerBean();    }}

将配置类集成到Application.java类中,

@SpringBootApplication@EnableResourceServer@EnableDiscoveryClient@EnableGlobalMethodSecurity(prePostEnabled = true)public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }    protected static class webSecurityConfig extends WebSecurityConfigurerAdapter;    protected static class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter;}

实现UserDetailsService类,

@Servicepublic class AuthUserDetailsService implements UserDetailsService {    @Autowired    private UserRepository repository;    @Override    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        User user = repository.findByUsername(username);        if (user == null) {            throw new UsernameNotFoundException(username);        }        return user;    }}

通过JPA查询数据库当前用户,密码匹配即可生成access-token.
测试, 通过curl命令发送POST请求到接口uaa/oauth/token:

curl -H "Authorization:Basic YnJvd3Nlcjo=" -d "grant_type=password&scope=ui&username=test01&password=123456" localhost:4000/uaa/oauth/token//得到结果{"access_token":"18471940-5d80-4f17-8b57-8bb920214121","token_type":"bearer","refresh_token":"db4ed1dc-8ce1-4b91-8fad-9749022fea64","expires_in":41394,"scope":"ui"}

得到access_token后,可以在请求中携带信息获得ResourceServer中的资源:

curl -H "Authorization:Bearer 057c2f03-e69a-446e-bdf1-2e9d183e8814" localhost/accounts/current//结果{"id":2,"name":"test01","description":"test01"}