說到oauth2其實很多人都不陌生,很多大的開放平臺的API接口的認證都是使用的oauth2實現的,本文主要是結合spring cloud來簡單的說下,如果有什麼不對的地方大家可以指出來。
先說下我這裏使用的spring boot和spring cloud的版本
<!-- spring boot配置 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- spring cloud 配置 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
不同的版本之間可能存在一定的差異性,所以請大家根據自己使用的版本進行調整。好了,廢話就不多說了,直接進入正題。
第一步:POM文件修改
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
第二步:創建啓動類,這裏是作爲認證服務器,所以追加註解@EnableAuthorizationServer
@SpringBootApplication
@EnableEurekaClient
@EnableAuthorizationServer
public class OAuthApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(OAuthApplication.class, args);
}
}
第三步:自定義AuthorizationServerConfig繼承AuthorizationServerConfigurerAdapter修改裏面的實現
/**
* 認證服務器配置
*
* @author 大仙
*
*/
@Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
//允許表單驗證
security.allowFormAuthenticationForClients();
// 開啓/oauth/token_key驗證端口無權限訪問
security.tokenKeyAccess("permitAll()");
// 開啓/oauth/check_token驗證端口認證權限訪問
security.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory() // 使用in-memory存儲
.withClient("client") // client_id
.secret(bCryptPasswordEncoder.encode("secret")) // client_secret
.authorizedGrantTypes("authorization_code") // 該client允許的授權類型
.scopes("app"); // 允許的授權範圍
}
}
這裏注意下幾個細節:
第一個對sercet要進行加密:.secret(bCryptPasswordEncoder.encode("secret")) // client_secret
第二個:如果沒有下面的配置是可以正常獲取code的,但是在請求access_token的時候會出現401的錯誤。
//允許表單驗證
security.allowFormAuthenticationForClients();
// 開啓/oauth/token_key驗證端口無權限訪問
security.tokenKeyAccess("permitAll()");
// 開啓/oauth/check_token驗證端口認證權限訪問
security.checkTokenAccess("isAuthenticated()");
第四步:spring security配置文件配置,如果不配置改類,在請求的code的時候會報錯。
/**
*
* @author 大仙
*
*/
@Configuration
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception { // @formatter:off
http.requestMatchers()
.antMatchers("/login", "/oauth/**")
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.permitAll()
.and().csrf().disable();
} // @formatter:on
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off
auth.inMemoryAuthentication()
.withUser("daxian")
.password(passwordEncoder().encode("123"))
.roles("USER");
} // @formatter:on
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
這裏的賬號密碼是放內存中的,注意密碼是需要加密的。
好了基本的配置完成,一次啓動 eureka,config,oauth
下面是獲取認證操作。
第一步:請求code
http://localhost:9004/oauth/authorize?response_type=code&client_id=client&redirect_uri=http://baidu.com
請求參數說明:
response_type:code代表獲取code值
client_id:客戶端的ID,必選項
redirect_uri:重定向URI,必選項
scope:申請的權限範圍,可選項
state:任意值,認證服務器會原樣返回,用於抵制CSRF(跨站請求僞造)攻擊。
如果沒有登錄,會調到登錄頁面
賬號密碼就是剛剛存內存裏面的,daxian 123
登錄成功之後跳轉授權頁面,選擇授權之後會重定向到baidu
到此code獲取完畢。
第二步:根據code獲取access_token
請求參數說明:
client_id:客戶端的ID,必選項。
client_secret:客戶端的密鑰,必選項。
grant_type:表示使用的授權模式,必選項。
redirect_uri:當前版本必選項
code: 當前獲取的code值
好了,簡單的授權模式就完成了,下一篇會講到怎麼使用數據庫,redis來實現用戶和token存儲。