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)