OAuth2共有5种模式,分别为:html
这里实现了比较简单的密码模式。web
<dependencies> <!-- web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- OAuth2 --> <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
server.port=9999 spring.profiles.active=simple
@Profile("simple") @Configuration @EnableAuthorizationServer //认证服务器注解 public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Autowired private AuthenticationManager authenticationManager; //密码模式必需要注入authenticationManager,不然会报找不到authenticationManager错误 @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception{ security.allowFormAuthenticationForClients(); super.configure(security); //若是没有支持allowFormAuthenticationForClients或者有支持可是url中没有client_id和client_secret的,走basic认证保护。致使在浏览器中输入获取access_token时,会弹出窗口要求认证。 } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception{ clients.inMemory() .withClient("client") //客户端名称 .secret(passwordEncoder.encode("client")) //客户端密码 .authorizedGrantTypes("password","refresh_token") //密码模式 .scopes("select") //受权范围 .resourceIds(ResourceServerConfig.RESOURCE_ID) //资源服务器的id,这个在资源服务器里有配置。 .accessTokenValiditySeconds(1200) //有效时间 .refreshTokenValiditySeconds(50000); //refresh_token的有效时间 } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints)throws Exception{ endpoints .authenticationManager(authenticationManager); //配置注入的authenticationManager super.configure(endpoints); } }
@Profile("simple") @Configuration @EnableResourceServer //资源服务器注解 public class ResourceServerConfig extends ResourceServerConfigurerAdapter { public static final String RESOURCE_ID = "authorizationserver"; //就是AuthorizationServerConfigurerAdapter中配置的那个,用来标识资源服务器 @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception{ super.configure(resources); resources.resourceId(RESOURCE_ID); //配置资源服务器的id } @Override public void configure(HttpSecurity http) throws Exception{ System.out.println("ResourceServerConfig中配置HttpSecurity对象执行"); http.requestMatchers().antMatchers("/me") //配置"/me"是受保护的资源。要区分开springsecurity保护的端点和ResourceServer保护的端点。 .and() .authorizeRequests() .anyRequest().authenticated(); } }
@Profile("simple") @Configuration @EnableWebSecurity(debug = true) //能够不开启 public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired //注册用户,放到内存中 public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception{ auth.inMemoryAuthentication() .withUser("user").password(passwordEncoder().encode("user")).roles("USER") .and() .withUser("admin").password(passwordEncoder().encode("admin")).roles("ADMIN"); } @Override //配置不拦截"/oauth/**",不然在申请access_token会要求先认证 protected void configure(HttpSecurity http) throws Exception{ System.out.println("SecurityConfiguration中配置的对象执行"); http .requestMatchers().anyRequest() .and() .authorizeRequests() .antMatchers("/oauth/**").permitAll(); } @Override public void configure(WebSecurity web) throws Exception{ super.configure(web); web.ignoring().antMatchers("favicon.ico"); } @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Bean //认证服务器中注入的authenticationManager就是从这里来的 @Override public AuthenticationManager authenticationManager() throws Exception{ return super.authenticationManager(); } }
@Profile("simple") @RestController public class MainController { @GetMapping("/") public String email(){ return "这里是主页"; } @GetMapping("/admin") public String admin(){ return "这里是admin"; } @GetMapping("/user") public String user(){ return "这里是admin"; } }
@Profile("simple") @RestController public class ResourceController { @RequestMapping("/me") public Principal me(Principal principal){ System.out.println(principal.toString()); return principal; } }
@Profile("simple") @SpringBootApplication public class AuthSimpleApplication { public static void main(String[] args) { SpringApplication.run(AuthSimpleApplication.class, args); } }
在postman中输入如下连接:spring
http://localhost:9999/oauth/token?username=user&password=user&grant_type=password&scope=select&client_id=client&client_secret=client
返回如下内容:浏览器
[阮一峰](http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html)