Spring-Security-Oauth整合Spring-Security,攔截器


程序的目的主要是,在自己開發的web項目中,即提供前端頁面調用訪問得接口(帶有安全機制),也提供第三方調用的API(基於授權認證的).

在整合的過程中發現SpringSecurity不能到即處理自己的web請求也處理第三方調用請求。所以采用攔截器攔截處理本地的web請求,spring-security-oauth對第三方認證請求進行認證與授權。如果對Oauth2.0不熟悉請參考Oauth2.0介紹,程序主要演示password模式和client模式。

官方樣例:

https://github.com/spring-projects/spring-security-oauth/blob/master/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java

1.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springboot</groupId>
<artifactId>testSpringBoot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>18_SpringBoot_codeStandard</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 繼承父包 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath></relativePath>
</parent>



<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- Spring Boot Mybatis 依賴 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
<!--mysql驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.25</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.2</version>
</dependency>
       <!-- freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--alibab json -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
   <!-- 存放token -->
    <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
             <!--security  -->
   <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
    <!--oauth  -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<!--單元測試 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--maven的插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<!-- 配置java版本 不配置的話默認父類配置的是1.6 -->
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

 

2.application.properties中增加redis配置

#設置session超時時間
server.session.timeout=2000
spring.redis.host=127.0.0.1
spring.redis.port=6379
#配置oauth2過濾的優先級
security.oauth2.resource.filter-order=3

3.第三方調用API

package com.niugang.controller;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OauthController {
@GetMapping("/api/product/{id}")
public String getProduct(@PathVariable String id) {
// for debug
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return "product id : " + id;
}
@GetMapping("/api/order/{id}")
public String getOrder(@PathVariable String id) {
// for debug
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return "order id : " + id;
}
}

 

AuthExceptionEntryPoint.java 自定義token授權失敗返回信息

package com.niugang.exception;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定義AuthExceptionEntryPoint用於tokan校驗失敗返回信息
 * 
 * @author niugang
 *
 */
public class AuthExceptionEntryPoint implements AuthenticationEntryPoint {
    @Override
     public void commence(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException authException) throws ServletException {

        Map<String, Object> map = new HashMap<>();
        //401 未授權
        map.put("error", "401");
        map.put("message", authException.getMessage());
        map.put("path", request.getServletPath());
        map.put("timestamp", String.valueOf(new Date().getTime()));
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.writeValue(response.getOutputStream(), map);
        } catch (Exception e) {
            throw new ServletException();
        }
    }
    
}

 

CustomAccessDeniedHandler.java 自定義token授權失敗返回信息

package com.niugang.exception;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;

@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
            AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        Map<String, Object> map = new HashMap<>();
        map.put("error", "403");
        map.put("message", accessDeniedException.getMessage());
        map.put("path", request.getServletPath());
        map.put("timestamp", String.valueOf(new Date().getTime()));
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.getWriter().write(objectMapper.writeValueAsString(map));
    }
}

 

以下為password模式通過用戶名和密碼獲取token失敗,自定義錯誤信息。

CustomOauthException.java

package com.niugang.exception;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;

/**
 * 
 * @ClassName:  CustomOauthException   
 * @Description:password模式錯誤處理,自定義登錄失敗異常信息
 * @author: niugang
 * @date:   2018年9月5日 下午9:44:38   
 * @Copyright: 863263957@qq.com. All rights reserved. 
 *
 */
@JsonSerialize(using = CustomOauthExceptionSerializer.class)
public class CustomOauthException extends OAuth2Exception {
    public CustomOauthException(String msg) {
        super(msg);
    }
}

 

CustomOauthExceptionSerializer.java

package com.niugang.exception;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.Map;

/**
 * 
 * @ClassName:  CustomOauthExceptionSerializer   
 * @Description:password模式錯誤處理,自定義登錄失敗異常信息
 * @author: niugang
 * @date:   2018年9月5日 下午9:45:03   
 * @Copyright: 863263957@qq.com. All rights reserved. 
 *
 */
public class CustomOauthExceptionSerializer extends StdSerializer<CustomOauthException> {
    
    private static final long serialVersionUID = 1478842053473472921L;

    public CustomOauthExceptionSerializer() {
        super(CustomOauthException.class);
    }
    @Override
    public void serialize(CustomOauthException value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        gen.writeStartObject();
        gen.writeStringField("error", String.valueOf(value.getHttpErrorCode()));
        gen.writeStringField("message", value.getMessage());
//      gen.writeStringField("message", "用戶名或密碼錯誤");
        gen.writeStringField("path", request.getServletPath());
        gen.writeStringField("timestamp", String.valueOf(new Date().getTime()));
       if (value.getAdditionalInformation()!=null) {
            for (Map.Entry<String, String> entry : 
            value.getAdditionalInformation().entrySet()) {
                String key = entry.getKey();
                String add = entry.getValue();
                gen.writeStringField(key, add);
            }
        }
        gen.writeEndObject();
    }
}

 

CustomWebResponseExceptionTranslator.java

package com.niugang.exception;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.stereotype.Component;

/**
 * 
 * @ClassName:  CustomWebResponseExceptionTranslator   
 * @Description:password模式錯誤處理,自定義登錄失敗異常信息
 * @author: niugang
 * @date:   2018年9月5日 下午9:46:36   
 * @Copyright: 863263957@qq.com. All rights reserved. 
 *
 */
@Component
public class CustomWebResponseExceptionTranslator implements WebResponseExceptionTranslator {
    @Override
    public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {

        OAuth2Exception oAuth2Exception = (OAuth2Exception) e;
        return ResponseEntity
                .status(oAuth2Exception.getHttpErrorCode())
                .body(new CustomOauthException(oAuth2Exception.getMessage()));
    }
}

 

4.配置授權認證服務器

package com.niugang.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import com.niugang.exception.AuthExceptionEntryPoint;

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.token.store.redis.RedisTokenStore;

@Configuration
/*
 * 在當前應用程序上下文中啟用授權服務器(即AuthorizationEndpoint和TokenEndpoint)的便利注釋,
 * 它必須是一個DispatcherServlet上下文。服務器的許多特性可以通過使用AuthorizationServerConfigurer類型的@
 * bean來定制(例如,通過擴展AuthorizationServerConfigurerAdapter)。用戶負責使用正常的Spring安全特性(
 * @EnableWebSecurity等)來保護授權端點(/oauth/授權),但是令牌端點(/oauth/
 * Token)將通過客戶端憑證上的HTTP基本身份驗證自動獲得。
 * 客戶端必須通過一個或多個AuthorizationServerConfigurers提供一個ClientDetailsService來注冊。
 */

@EnableAuthorizationServer

public class AuthorizationServerConfiguration  extends AuthorizationServerConfigurerAdapter {
//模擬第三方調用api
private static final String DEMO_RESOURCE_ID = "api";
    @Autowired
      AuthenticationManager authenticationManager;
      @Autowired
      RedisConnectionFactory redisConnectionFactory;
      @Autowired
      private UserDetailsService userDetailsService;
      @Autowired
      private WebResponseExceptionTranslator customWebResponseExceptionTranslator;


      /**accessTokenValiditySeconds:設置token無效時間,秒
       * refreshTokenValiditySeconds:設置refresh_token無效時間秒
       */

      @Override

     public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
          //配置兩個客戶端,一個用於password認證一個用於client認證
          clients.inMemory().withClient("client_1")//基於客戶端認證的
                  .resourceIds(DEMO_RESOURCE_ID)
                  .authorizedGrantTypes("client_credentials", "refresh_token")
                  .scopes("select")
                  .authorities("client")
                  .secret("123456")/*.refreshTokenValiditySeconds(3600).accessTokenValiditySeconds(60)*/
                  .and().withClient("client_2")//基於密碼的
                  .resourceIds(DEMO_RESOURCE_ID)
                  .authorizedGrantTypes("password", "refresh_token")
                  .scopes("select")
                  .authorities("client")
                  .secret("123456")/*.refreshTokenValiditySeconds(3600).accessTokenValiditySeconds(60)*/;
                 
      }

 @Override
      public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
          endpoints
                  .tokenStore(new RedisTokenStore(redisConnectionFactory))
                  .authenticationManager(authenticationManager)
                  .userDetailsService(userDetailsService);//密碼模式需要在數據庫中進行認證
         endpoints.exceptionTranslator(customWebResponseExceptionTranslator);//錯誤異常
      }
      @Override
      public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
          //允許表單認證
          oauthServer.allowFormAuthenticationForClients();
          oauthServer.authenticationEntryPoint(new AuthExceptionEntryPoint());
      }
}

 

5.配置資源服務器

package com.niugang.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
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 com.niugang.exception.AuthExceptionEntryPoint;
import com.niugang.exception.CustomAccessDeniedHandler;

/**
 * 配置資源服務器
 * 
 * @author niugang
 *
 */
@Configuration
@EnableResourceServer
/**
 * 為OAuth2資源服務器提供方便的注釋,使Spring security過濾器能夠通過傳入的OAuth2令牌驗證請求。用戶應該添加這個注釋,
 * 並提供一個名為ResourceServerConfigurer的@Bean(例如,通過ResourceServerConfigurerAdapter),
 * 它指定了資源的詳細信息(URL路徑和資源id)。為了使用這個過濾器,您必須在您的應用程序中的某個地方使用@EnableWebSecurity,
 * 或者在您使用這個注釋的地方,或者在其他地方。
 * 
 * 
 *

 */

public class ResourceServerConfiguration  extends ResourceServerConfigurerAdapter{
private static final String DEMO_RESOURCE_ID = "api";
@Autowired
private CustomAccessDeniedHandler customAccessDeniedHandler;
@Override
     public void configure(ResourceServerSecurityConfigurer resources) {
//resourceId:指定可訪問的資源id
//stateless:標記,以指示在這些資源上只允許基於標記的身份驗證。
         resources.resourceId(DEMO_RESOURCE_ID).stateless(true);
resources.authenticationEntryPoint(new AuthExceptionEntryPoint());
        resources.accessDeniedHandler(customAccessDeniedHandler);
     }


     @Override
     public void configure(HttpSecurity http) throws Exception {
   
         http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
         .and()
         .authorizeRequests() 
         .antMatchers("/api/**").authenticated();//配置api訪問控制,必須認證過后才可以訪問
     }
}

 


6.配置springsecurity

package com.niugang.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
/**
 * 雖然和oauth認證優先級,起了沖突但是啟動也會放置不安全的攻擊
 * @author niugang
 *
 */
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {




@Override
protected void configure(HttpSecurity http) throws Exception {

http
             .authorizeRequests()
             .antMatchers("/oauth/**").permitAll();
}


}

 

7.增加攔截器

package com.niugang.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LogInterceptor implements HandlerInterceptor {
private static Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
    /**
     * 執行攔截器之前
     */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info("interceptor....在執行前...url:{}", request.getRequestURL());
String user = (String)request.getSession().getAttribute("user");
if(user==null){
response.sendRedirect("/myweb/login");
}
return true; //返回false將不會執行了
}

/**
* 調用完處理器,渲染視圖之前
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.info("interceptor.......url:{}", request.getRequestURL());
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}

 

 

8.配置攔截器

package com.niugang.config;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
/**
* 授權攔截的路徑 addPathPatterns:攔截的路徑 excludePathPatterns:不攔截的路徑
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new com.niugang.interceptor.LogInterceptor()).addPathPatterns("/**").excludePathPatterns("/login/**",
"/static/*","/api/**");//"/api/**",不攔截第三方調用的api
super.addInterceptors(registry);
}

/**
* 修改springboot中默認的靜態文件路徑
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//addResourceHandler請求路徑
//addResourceLocations 在項目中的資源路徑
//setCacheControl 設置靜態資源緩存時間
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic());
super.addResourceHandlers(registry);
}
}

 


9.配置配置springsecurity數據庫認證

package com.niugang.service;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.niugang.bean.UserQuery;
import com.niugang.entity.User;
import com.niugang.exception.CheckException;
/**
 * 授權認證業務類
 * 
 * @author niugang UserDetailsService spring security包里面的
 * 重寫loadUserByUsername方法
 *
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
//UserService自定義的,從數據查詢信息
@Resource
private UserService userService;

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserQuery user = new UserQuery();
user.setName(username);
// 查詢用戶是否存在
List<User> queryList = userService.queryListByPage(user);
if (queryList != null & queryList.size() == 1) {
// 查詢用戶擁有的角色
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
//如果是admin用戶登錄,授予SUPERADMIN權限
if(username.equals("admin")){
list.add(new SimpleGrantedAuthority("SUPERADMIN"));
}

org.springframework.security.core.userdetails.User authUser = new org.springframework.security.core.userdetails.User(
queryList.get(0).getName(), queryList.get(0).getPassword(), list);


return authUser;
}
return null;

}
}

 

 

如訪問:http:://localhost:8080/myweb/index,沒有登錄就會跳轉到登錄頁面通過以上配置,對於所有web請求,如果沒有登錄都會跳轉到登錄頁面,攔截器不會攔截調用api的請求。

訪問http:://localhost:8080/myweb/api/order/1會提示沒有權限需要認證,默認錯誤與我們自定義返回信息不一致,並且描述信息較少。那么如何自定義Spring Security Oauth2異常信息,上面也已經有代碼實現

    (默認的)

(自定義的)

獲取token
進行如上配置之后,啟動springboot應用就可以發現多了一些自動創建的endpoints(項目啟動的時候也會打印mappings):
{[/oauth/authorize]}
{[/oauth/authorize],methods=[POST]
{[/oauth/token],methods=[GET]}
{[/oauth/token],methods=[POST]}
{[/oauth/check_token]}

{[/oauth/error]

通過單元測試,獲取client模式的token

package com.niugang;
import java.util.HashMap;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Test {

@org.junit.Test
public void  queryToken() {
    RestTemplate restTemplate = new RestTemplate();
    HashMap<String, String> hashMap = new HashMap<>();
    hashMap.put("grant_type", "client_credentials");
    hashMap.put("scope", "select");
    hashMap.put("client_id", "client_1");
    hashMap.put("client_secret", "123456");
    ResponseEntity<String> postForEntity =     restTemplate.postForEntity("http://localhost:8080/myweb/oauth/token?grant_type={grant_type}&scope={scope}&client_id={client_id}&client_secret={client_secret}",     String.class,
    String.class, hashMap);
    String body = postForEntity.getBody();
    System.out.println(body);
}
}

 

 


{"access_token":"5bf8c55d-874d-41fc-94bc-01e2cb8f7142","token_type":"bearer","expires_in":43199,"scope":"select"}

expires_in:訪問令牌數秒內的生命周期。例如,值“3600”表示訪問令牌將在響應生成后一小時內過期

 

然后在訪問:訪問http://localhost:8080/myweb/api/order/1?access_token=bbc81328-69f6-4ff0-8c4c-512f1b8beea3

 

密碼模式也是一樣就是放說需要的參數變了

注意此列中的密碼模式是基於數據認證的,所以獲取token之前確保數據庫有對應的username和password

  /**
     * 密碼模式
     */
@org.junit.Test
public void queryToken2() {
     RestTemplate restTemplate = new RestTemplate();
    HashMap<String, String> hashMap = new HashMap<>();
    hashMap.put("username", "haha");
    hashMap.put("password", "123456");
    hashMap.put("grant_type", "password");
    hashMap.put("scope", "select");
    hashMap.put("client_id", "client_2");
    hashMap.put("client_secret", "123456");
    ResponseEntity<String> postForEntity = restTemplate.postForEntity(
    "http://localhost:8080/myweb/oauth/token?username={username}&password=            {password}&grant_type={grant_type}&scope={scope}&client_id={client_id}&client_secret=        {client_secret}",
    String.class, String.class, hashMap);
    String body = postForEntity.getBody();
    System.out.println(body);
}

 

 

{"access_token":"39aa6302-6614-4b94-8553-a96d9ba0f893","token_type":"bearer","refresh_token":"7f2f41dd-4406-4df4-997a-d80178431db8","expires_in":43199,"scope":"select"}   //密碼模式返回了refresh_token

源碼地址:https://gitee.com/niugangxy/springboot

 微信公眾號

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM