package com.icecloud.cloud.test.oauthTest_1; import java.util.LinkedHashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.ManagementServerProperties; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController @EnableAuthorizationServer @Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER) public class App extends WebSecurityConfigurerAdapter { /** * 須要權限的action */ @RequestMapping({ "/test" }) public Map<String, String> test() { Map<String, String> map = new LinkedHashMap<String, String>(); map.put("nametest", "12222"); return map; } /** * 須要權限而且提供token才能訪問的action */ @RequestMapping({ "/se" }) public Map<String, String> se() { Map<String, String> map = new LinkedHashMap<String, String>(); map.put("se", "3333"); return map; } /** * 不須要權限的action */ @RequestMapping({ "/","" }) public String index() { return "index"; } public static void main(String[] args) { SpringApplication.run(App.class, args); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/").permitAll() .anyRequest().authenticated() .and() .formLogin() .and() .httpBasic(); } @Autowired public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user").password("user").roles("USER"); } /** * 資源服務器 * @author penghaozhong * */ @Configuration @EnableResourceServer protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @Override public void configure(ResourceServerSecurityConfigurer resources) { resources.resourceId("app").stateless(false); } @Override public void configure(HttpSecurity http) throws Exception { http .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .and() .requestMatchers().antMatchers("/se") .and() .authorizeRequests() .antMatchers("/se").access("#oauth2.hasScope('read')"); } } /** * oauth2 服務端 * @author penghaozhong * */ @Configuration @EnableAuthorizationServer protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient("tonr").secret("secret").authorizedGrantTypes("authorization_code") .scopes("read"); } } }
一個完成的oauth2 例子 。服務端和資源服務器同爲一個。下面進行代碼拆分理解。java
本例子中有三個重要的組件:security ResourceServer AuthorizationServerweb
public class App extends WebSecurityConfigurerAdapter
WebSecurityConfigurerAdapter 默認是要求進行帳號密碼登陸操做的,即便你沒有編寫.formLogin(),由於系統用上了默認配置。spring
WebSecurityConfigurerAdapter 類中:有這段代碼緩存
protected void configure(HttpSecurity http) throws Exception { logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity)."); http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().and() .httpBasic(); }
security帳號密碼配置方式,記住這裏的帳號密碼是用戶登陸時用的。配置有2種形式:服務器
@Autowired public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user").password("user").roles("USER"); }
@Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient("tonr").secret("secret").authorizedGrantTypes("authorization_code") .scopes("read"); }
@Override public void configure(HttpSecurity http) throws Exception { http .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .and() .requestMatchers().antMatchers("/se") .and() .authorizeRequests() .antMatchers("/se").access("#oauth2.hasScope('read')"); }
代碼編寫已經理解完成。下面進行實際測試工做吧。session
這裏我用的postman進行調試的。用到authorization的oauth2.0功能 ,很方便進行調試工做。各個參數按照要求填入便可。點擊請求後在後臺日志中會獲得code。app
這裏須要用上一把的code值去換取token,獲取token時就用post方式獲取。填入須要參數後,你會發現這裏有個坑。這裏賣個關子,若是你沒有遇到沒有解決又沒太多時間去解決的話,留言便可。less
大工搞成,但願這篇文章能幫到須要的朋友們。半夜睡不着能夠起來調程序,頗有樂趣!ide