日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

nacos oaut服务地址_用户认证的例子:Spring Security oAuth2 + Spring Cloud Gateway + Nacos + Dubbo...

發布時間:2024/4/19 javascript 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 nacos oaut服务地址_用户认证的例子:Spring Security oAuth2 + Spring Cloud Gateway + Nacos + Dubbo... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這個例子是商城后臺項目的一部分,主要使用了oAuth2的密碼模式完成用戶名密碼認證功能。主要流程是:使用Nacos作為注冊中心,操作用戶的服務user-mgr-service作為服務提供者,注冊到Nacos,通過Dubbo供oAuth2調用,同時oAuth2也作為Rest服務提供者,注冊到Nacos,提供用戶登錄/user/login服務。網關Gateway也注冊到Nacos,提供統一入口,路由到oAuth2服務,完成用戶認證。

(文章主要寫一下實現步驟,具體代碼附上的話太多了,影響閱讀。github.com/toyranger/c…)

1. Spring Security oAuth2 密碼模式

1.1 密碼模式和授權碼模式

{placeholder}

2. oAuth2實現認證服務器

2.1 創建授權服務器

ClientDetailsServiceConfigurer:通過配置的數據源,配置ClientDetailsService

AuthorizationServerSecurityConfigurer:用來配置令牌端點(Token Endpoint)的安全約束.

AuthorizationServerEndpointsConfigurer:用來配置授權(authorization)以及令牌(token)

@Configuration

@EnableAuthorizationServer

public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

@Autowired

private BCryptPasswordEncoder passwordEncoder;

@Bean

@Primary

@ConfigurationProperties(prefix = "spring.datasource")

public DataSource dataSource() {

return DataSourceBuilder.create().build();

}

@Bean

public TokenStore tokenStore() {

return new JdbcTokenStore(dataSource());

}

@Bean

public ClientDetailsService jdbcClientDetailsService() {

return new JdbcClientDetailsService(dataSource());

}

/***

* 用于支持密碼模式

*/

@Autowired

private AuthenticationManager authenticationManager;

@Override

public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore());

}

@Override

public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {

// 允許客戶端訪問 /oauth/check_token檢查token

security.checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients();

}

@Override

public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

clients.withClientDetails(jdbcClientDetailsService());

}

/***

* 內存模式

*/

// @Override

// public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

//

// clients.inMemory()

// .withClient("client")

// .secret(passwordEncoder.encode("secret"))

// .authorizedGrantTypes("password", "refresh_token")

// .scopes("backend")

// .resourceIds("backend-resources")

// .accessTokenValiditySeconds(60 * 60 * 24)

// .refreshTokenValiditySeconds(60 * 60 * 24 * 30);

// }

}

復制代碼

2.2 創建認證服務器和資源服務器

認證服務器的任務是根據用戶名查詢用戶,以及用戶所具有的權限,資源服務器的任務是配置訪問資源(url)所需要的對應的權限。這里把他們寫在一個Configuration中

@Configuration

@EnableWebSecurity

@EnableResourceServer

public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Bean

public BCryptPasswordEncoder passwordEncoder() {

return new BCryptPasswordEncoder();

}

@Bean

public UserDetailsService userDetailsService() {

return new UserDetailsServiceImpl();

}

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.userDetailsService(userDetailsService());

}

/***

* 用于支持 password 模式

* @return

* @throws Exception

*/

@Bean

@Override

public AuthenticationManager authenticationManagerBean() throws Exception {

return super.authenticationManagerBean();

}

@Override

public void configure(WebSecurity web) throws Exception {

web.ignoring().antMatchers("/user/login");

}

@Override

protected void configure(HttpSecurity http) throws Exception {

http.exceptionHandling().and()

.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

.and()

.authorizeRequests()

.antMatchers("/user/info").hasAnyAuthority("UserInfo")

.antMatchers("/user/logout").hasAnyAuthority("UserLogout");

}

}

復制代碼

2.3 在用戶認證的userDetailsService中,需要通過Dubbo調用user-mgr-service提供的服務

public class UserDetailsServiceImpl implements UserDetailsService {

@Reference(version = "1.0.0")

private UserMgrApi userMgrApi;

@Reference(version = "1.0.0")

private PermissionMgrApi permissionMgrApi;

@Override

public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

User userByName = userMgrApi.selectOne(s);

if (null == userByName) {

return null;

}

List grantedAuthorities = Lists.newArrayList();

List permissions = permissionMgrApi.selectListByUserId(userByName.getId());

permissions.forEach(permission -> {

GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getEnname());

grantedAuthorities.add(grantedAuthority);

});

return new org.springframework.security.core.userdetails.User(userByName.getUsername(),

userByName.getPassword(), grantedAuthorities);

}

}

用戶信息是基于RBAC授權模型,通過username查詢用戶,查到用戶之后通過userId查詢對應的權限,都是很簡單的dao操作,使用mybatis(plus)就可以完成。

復制代碼

3. oAuth2對外提供rest接口,/user/login

oAuth2密碼需要傳username、password、grant_type、client_id、client_secret五個參數,而用戶只需要傳username和password即可,所以其余的參數需要登錄服務自己傳過去。

這里使用RestTemplate,向oAuth2服務發起請求。

成功認證之后,會得到Token。

@PostMapping("/user/login")

public CommonsResponse login(@RequestBody LoginParam loginParam) {

String tokenUrl = "http://localhost:8091/oauth/token";

MultiValueMap multiValueMap = new LinkedMultiValueMap<>();

multiValueMap.add("username", loginParam.getUsername());

multiValueMap.add("password", loginParam.getPassword());

multiValueMap.add("grant_type", oauth2_grant_type);

multiValueMap.add("client_id", oauth2_client_id);

multiValueMap.add("client_secret", oauth2_client_secret);

HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

HttpEntity> entity = new HttpEntity<>(multiValueMap, headers);

TokenEntity tokenEntity;

try {

tokenEntity = restTemplate.postForObject(tokenUrl, entity, TokenEntity.class);

} catch (Exception e) {

tokenEntity = null;

}

if (null == tokenEntity) {

return new CommonsResponse(BaseStatusEnum.UNAUTHORIZED.getIndex(),

BaseStatusEnum.UNAUTHORIZED.getMsg(), null);

}

return new CommonsResponse(BaseStatusEnum.SUCCESS.getIndex(), BaseStatusEnum.SUCCESS.getMsg(),

tokenEntity);

}

復制代碼

4. 加入網關Gateway

網關可以限流和熔斷,為應用提供統一的入口。這里只使用了基本的功能。

cloud:

nacos:

discovery:

server-addr: localhost:8848

gateway:

# 設置與服務注冊發現組件結合,這樣可以采用服務名的路由策略

discovery:

locator:

enable: true

routes:

- id: BUSINESS-OAUTH2

# 采用LoadBalanceClient方式請求,以lb://開頭,后面跟注冊在nacos上的服務名

uri: lb://business-security

# 斷言,或者叫謂詞

predicates:

- Path=/api/user/**

filters:

- StripPrefix=1

復制代碼

5. 運行示例

5.1 注冊到Nacos:

5.2 訪問網關:

5.3 測試token權限

可以看到在資源服務中配置了

.antMatchers("/user/info").hasAnyAuthority("UserInfo"),即訪問/user/info需要UserInfo權限,而此時RBAC表中,"user"用戶具有這個權限

所以可以訪問成功

此時如果我把"user"用戶的/user/logout權限去掉(對應的表是tb_role_permission),那么他訪問這個url的時候就會返回沒有權限:

(好像是,修改了權限,之前獲取的token就會失效,需要重新獲取)

總結

以上是生活随笔為你收集整理的nacos oaut服务地址_用户认证的例子:Spring Security oAuth2 + Spring Cloud Gateway + Nacos + Dubbo...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。