赞
踩
- <dependency>
- <groupId>io.jsonwebtoken</groupId>
- <artifactId>jjwt</artifactId>
- <version>0.9.0</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-data</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-oauth2</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.security.oauth.boot</groupId>
- <artifactId>spring-security-oauth2-autoconfigure</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework.security.oauth.boot</groupId>
- <artifactId>spring-security-oauth2-autoconfigure</artifactId>
- <version>2.1.3.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-security</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.31</version>
- </dependency>

- package com.zb.oauth.cofig;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- 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.configurers.AuthorizationServerEndpointsConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
- import org.springframework.security.oauth2.provider.ClientDetailsService;
- import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
- import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.TokenStore;
- import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
- import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
-
- import javax.annotation.Resource;
- import javax.sql.DataSource;
- import java.security.KeyPair;
-
-
- @Configuration
- @EnableAuthorizationServer
- class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
- //SpringSecurity 用户自定义授权认证类
- @Autowired
- UserDetailsService userDetailsService;
- //授权认证管理器
- @Autowired
- AuthenticationManager authenticationManager;
- //令牌持久化存储接口
- @Autowired
- TokenStore tokenStore;
- //数据源,用于从数据库获取数据进行认证操作,测试可以从内存中获取
- @Autowired
- private DataSource dataSource;
- //jwt令牌转换器
- @Autowired
- private JwtAccessTokenConverter jwtAccessTokenConverter;
- @Autowired
- private CustomUserAuthenticationConverter customUserAuthenticationConverter;
- @Resource(name = "keyProp")
- private KeyProperties keyProperties;
-
- /***
- * 客户端信息配置
- * @param clients
- * @throws Exception
- */
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
- clients.jdbc(dataSource).clients(this.clientDetails());
- // clients.inMemory()
- // .withClient("changgou") //客户端id
- // .secret("changgou") //秘钥
- // .redirectUris("http://localhost") //重定向地址
- // .accessTokenValiditySeconds(3600) //访问令牌有效期
- // .refreshTokenValiditySeconds(3600) //刷新令牌有效期
- // .authorizedGrantTypes(
- // "authorization_code", //根据授权码生成令牌
- // "client_credentials", //客户端认证
- // "refresh_token", //刷新令牌
- // "password") //密码方式认证
- // .scopes("app"); //客户端范围,名称自定义,必填
- }
-
- /***
- * 授权服务器端点配置
- * @param endpoints
- * @throws Exception
- */
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
- endpoints.accessTokenConverter(jwtAccessTokenConverter)
- .authenticationManager(authenticationManager)//认证管理器
- .tokenStore(tokenStore) //令牌存储
- .userDetailsService(userDetailsService); //用户信息service
- }
-
- /***
- * 授权服务器的安全配置
- * @param oauthServer
- * @throws Exception
- */
- @Override
- public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
- oauthServer.allowFormAuthenticationForClients()
- .passwordEncoder(new BCryptPasswordEncoder())
- .tokenKeyAccess("permitAll()")
- .checkTokenAccess("isAuthenticated()");
- }
-
- //读取密钥的配置
- @Bean("keyProp")
- public KeyProperties keyProperties() {
- return new KeyProperties();
- }
-
- //客户端配置
- @Bean
- public ClientDetailsService clientDetails() {
- return new JdbcClientDetailsService(dataSource);
- }
-
- @Bean
- @Autowired
- public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
- return new JwtTokenStore(jwtAccessTokenConverter);
- }
-
- /****
- * JWT令牌转换器
- * @param customUserAuthenticationConverter
- * @return
- */
- @Bean
- public JwtAccessTokenConverter jwtAccessTokenConverter(CustomUserAuthenticationConverter customUserAuthenticationConverter) {
- JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
- KeyPair keyPair = new KeyStoreKeyFactory(
- keyProperties.getKeyStore().getLocation(), //证书路径 changgou.jks
- keyProperties.getKeyStore().getSecret().toCharArray()) //证书秘钥 changgouapp
- .getKeyPair(
- keyProperties.getKeyStore().getAlias(), //证书别名 changgou
- keyProperties.getKeyStore().getPassword().toCharArray()); //证书密码 changgou
- converter.setKeyPair(keyPair);
- //配置自定义的CustomUserAuthenticationConverter
- DefaultAccessTokenConverter accessTokenConverter = (DefaultAccessTokenConverter) converter.getAccessTokenConverter();
- accessTokenConverter.setUserTokenConverter(customUserAuthenticationConverter);
- return converter;
- }
- }
-

- package com.zb.oauth.cofig;
-
- import com.zb.oauth.util.UserJwt;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.authority.AuthorityUtils;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
- import org.springframework.stereotype.Component;
-
- import java.util.LinkedHashMap;
- import java.util.Map;
-
- @Component
- public class CustomUserAuthenticationConverter extends DefaultUserAuthenticationConverter {
-
- @Autowired
- UserDetailsService userDetailsService;
-
- @Override
- public Map<String, ?> convertUserAuthentication(Authentication authentication) {
- LinkedHashMap response = new LinkedHashMap();
- String name = authentication.getName();
- response.put("username", name);
-
- Object principal = authentication.getPrincipal();
- UserJwt userJwt = null;
- if (principal instanceof UserJwt) {
- userJwt = (UserJwt) principal;
- } else {
- //refresh_token默认不去调用userdetailService获取用户信息,这里我们手动去调用,得到 UserJwt
- UserDetails userDetails = userDetailsService.loadUserByUsername(name);
- userJwt = (UserJwt) userDetails;
- }
- response.put("name", userJwt.getName());
- response.put("id", userJwt.getId());
- //公司 response.put("compy", "songsi");
- if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
- response.put("authorities", AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
- }
- return response;
- }
-
- }

- package com.zb.oauth.cofig;
-
- import com.zb.client.UserModelFeignClient;
- import com.zb.oauth.util.UserJwt;
- import com.zb.dto.UserModelDto;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.authority.AuthorityUtils;
- import org.springframework.security.core.context.SecurityContextHolder;
- import org.springframework.security.core.userdetails.User;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.core.userdetails.UsernameNotFoundException;
- import org.springframework.security.oauth2.provider.ClientDetails;
- import org.springframework.security.oauth2.provider.ClientDetailsService;
- import org.springframework.stereotype.Service;
- import org.springframework.util.ObjectUtils;
- import org.springframework.util.StringUtils;
-
- /*****
- * 自定义授权认证类
- */
- @Service
- public class UserDetailsServiceImpl implements UserDetailsService {
-
- @Autowired
- ClientDetailsService clientDetailsService;
-
- @Autowired
- private UserModelFeignClient userModelFeignClient;
-
- /****
- * 自定义授权认证
- * @param username
- * @return
- * @throws UsernameNotFoundException
- */
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- //取出身份,如果身份为空说明没有认证
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- //没有认证统一采用httpbasic认证,httpbasic中存储了client_id和client_secret,开始认证client_id和client_secret
- if (authentication == null) {
- ClientDetails clientDetails = clientDetailsService.loadClientByClientId(username);
- if (clientDetails != null) {
- //秘钥
- String clientSecret = clientDetails.getClientSecret();
- //静态方式
- // return new User(username,new BCryptPasswordEncoder().encode(clientSecret), AuthorityUtils.commaSeparatedStringToAuthorityList(""));
- //数据库查找方式
- return new User(username, clientSecret, AuthorityUtils.commaSeparatedStringToAuthorityList(""));
- }
- }
-
- if (StringUtils.isEmpty(username)) {
- return null;
- }
- //feign远程调用用户微服务的登录放法,获取用户dto对象
- UserModelDto info = userModelFeignClient.info(username);
-
- if (ObjectUtils.isEmpty(info)) {
- return null;
- }
-
- //根据用户名查询用户信息
- String pwd = info.getPassword();
- //创建User对象
- //用户权力
- String permissions = "";
-
-
- UserJwt userDetails = new UserJwt(username, pwd, AuthorityUtils.commaSeparatedStringToAuthorityList(permissions));
-
-
- return userDetails;
- }
- }

- package com.zb.oauth.cofig;
-
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.annotation.Order;
- import org.springframework.security.authentication.AuthenticationManager;
- 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.builders.WebSecurity;
- import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.crypto.password.PasswordEncoder;
-
- @Configuration
- @EnableWebSecurity
- @Order(-1)
- class WebSecurityConfig extends WebSecurityConfigurerAdapter {
-
- /***
- * 忽略安全拦截的URL
- * @param web
- * @throws Exception
- */
- @Override
- public void configure(WebSecurity web) throws Exception {
- web.ignoring().antMatchers(
- "/my-auth/login/**",
- "/user/logout");
- }
-
- /***
- * 创建授权管理认证对象
- * @return
- * @throws Exception
- */
- @Bean
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- AuthenticationManager manager = super.authenticationManagerBean();
- return manager;
- }
-
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- super.configure(auth);
- }
-
- /***
- * 采用BCryptPasswordEncoder对密码进行编码
- * @return
- */
- @Bean
- public PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
-
- /****
- *
- * @param http
- * @throws Exception
- */
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.csrf().disable()
- .httpBasic() //启用Http基本身份验证
- .and()
- .formLogin() //启用表单身份验证
- .and()
- .authorizeRequests() //限制基于Request请求访问
- .anyRequest()
- .authenticated(); //其他请求都需要经过验证
-
- }
- }

- package com.zb.oauth.util;
-
- import java.io.Serializable;
-
-
- public class AuthToken implements Serializable {
-
- //令牌信息
- String accessToken;
- //刷新token(refresh_token)
- String refreshToken;
- //jwt短令牌
- String jti;
-
- public String getAccessToken() {
- return accessToken;
- }
-
- public void setAccessToken(String accessToken) {
- this.accessToken = accessToken;
- }
-
- public String getRefreshToken() {
- return refreshToken;
- }
-
- public void setRefreshToken(String refreshToken) {
- this.refreshToken = refreshToken;
- }
-
- public String getJti() {
- return jti;
- }
-
- public void setJti(String jti) {
- this.jti = jti;
- }
- }

- package com.zb.oauth.util;
-
-
- import org.springframework.security.core.GrantedAuthority;
- import org.springframework.security.core.userdetails.User;
-
- import java.util.Collection;
-
-
- public class UserJwt extends User {
- private String id; //用户ID
- private String name; //用户名字
-
- private String comny;//设置公司
-
- public UserJwt(String username, String password, Collection<? extends GrantedAuthority> authorities) {
- super(username, password, authorities);
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }

- package com.zb.oauth.service.impl;
-
- import com.zb.oauth.service.AuthService;
- import com.zb.oauth.util.AuthToken;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.cloud.client.ServiceInstance;
- import org.springframework.cloud.client.discovery.DiscoveryClient;
- import org.springframework.http.HttpEntity;
- import org.springframework.http.HttpMethod;
- import org.springframework.http.ResponseEntity;
- import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
- import org.springframework.stereotype.Service;
- import org.springframework.util.Base64Utils;
- import org.springframework.util.LinkedMultiValueMap;
- import org.springframework.web.client.RestTemplate;
-
- import java.sql.ClientInfoStatus;
- import java.util.List;
- import java.util.Map;
-
- @Service
- public class AutoServiceImpl implements AuthService {
- @Autowired
- private RestTemplate restTemplate;
-
- @Autowired
- private DiscoveryClient discoveryClient;
-
- @Override
- public AuthToken login(String username, String passwd, String clientId, String clientSecret) {
- //根据微服务name获取接口类型list集合
- List<ServiceInstance> instances = discoveryClient.getInstances("user-auth");
- //取第一个接口获取ip和端口号生成url地址
- ServiceInstance serviceInstance = instances.get(0);
- String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/oauth/token";
- System.out.println(url);
- //创建一个LinkedMultiValueMap的body
- LinkedMultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();
- //给body添加需要的参数
- body.add("grant_type", "password");
- body.add("username", username);
- body.add("password", passwd);
- //创建一个LinkedMultiValueMap的header
- LinkedMultiValueMap<String, String> header = new LinkedMultiValueMap<String, String>();
- //给请求头添加参数
- //调用本类的myEncoder方法编译
- header.add("Authorization", myEncoder(clientId, clientSecret));
- try {
- //用restTemplate.exchange()发起请求,
- //方法参数:地址,请求方式,HttpEntity<>(请求体,请求头),返回数据的类型
- //创建一个ResponseEntity<返回数据的类型>的response对象接收POST请求返回的数据
- ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, header), Map.class);
- //调用getBody()获取response对象中返回的map
- Map map = response.getBody();
- System.out.println(map);
- //创建AuthToken对象并初始化
- AuthToken authToken = new AuthToken();
- authToken.setAccessToken(map.get("access_token").toString());
- authToken.setJti(map.get("jti").toString());
- authToken.setRefreshToken(map.get("refresh_token").toString());
- return authToken;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- //clientId,clientId在application.yml配置文件中赋值
- //在controller层使用@Value("${auth.clientId}"),@Value("${auth.clientSecret}")获取
- private String myEncoder(String clientId, String clientSecret) {
- String str = clientId + ":" + clientSecret;
- byte[] encode = Base64Utils.encode(str.getBytes());
- return "Basic " + new String(encode);
- }
- }

- package com.zb.oauth.controller;
-
- import com.zb.oauth.service.AuthService;
- import com.zb.oauth.util.AuthToken;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.RestController;
-
- @RestController
- @RequestMapping("my-auth")
- public class AuthController {
- @Value("${auth.clientId}")
- private String clientId;
- @Value("${auth.clientSecret}")
- private String clientSecret;
- @Autowired
- private AuthService authService;
-
- @PostMapping("login")
- public AuthToken login(@RequestParam("username") String username, @RequestParam("passwd") String passwd) {
- return authService.login(username, passwd, clientId, clientSecret);
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。