当前应用需要实现第三方登入,那么第三方是如何进行授权认证的?这就是oauth2协议。

模拟实现微信端是如何进行授权认证登入。

举例:豆瓣就是客户应用,授权服务器、资源服务器就是微信端持有。豆瓣需要向微信的授权服务器获取授权,获取到授权后再向资源服务器获取用户信息。

那么我们就需要

1.需要配置一个授权服务器(发放授权码)

2.配置一个资源服务器(获取用户信息接口需要令牌才能访问)

3.配置一个接口(获取返回用户信息)

4.还要实现模拟用户的登入(因为授权服务器需要向用户发起是否允许授权的请求)

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_服务器

在spring-security-oauth2中有这几个默认接口,按照以下接口访问顺序获取用户信息:

/oauth/authorize:获取授权码 /oauth/token:根据授权码获取令牌 /user/getUser:根据令牌获取user资源信息

整个项目结构

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_服务器_02

项目依赖的pom文件:

注意:spring-cloud和spring-boot的版本一定要兼容适配,否则会报错

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
    </dependencies>
<dependencyManagement>
    <dependencies>
        <!--springCloud的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

 授权服务器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;
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;

/**
 * 授权服务器配置,客服端向此请求获取授权码
 *
 * 访问以下地址获取授权码:以下地址就是获取授权码的配置
 * http://localhost:8080/oauth/authorize?client_id=admin&response_type=code
 *
 * /oauth/authorize:获取授权码接口
 * response type=code:响应类型为授权码
 * client_d=admin:访问的授权服务器id
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("admin") // 配置client-id
                .secret(passwordEncoder.encode("12334")) // 授权服务器的密码
                .accessTokenValiditySeconds(3600) // 时间有效期
                .redirectUris("http://www.baidu.com") // 授权成功后跳转地址(并且会带上授权码code)
                .scopes("all") // 授权范围
                .authorizedGrantTypes("authorization_code"); // 授权码模式
    }
}

 资源服务器

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

/**
 * 资源服务管理,配置某些接口需要携带令牌才能访问获取资源
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .requestMatchers()
                .antMatchers("/user/**");// 需要携带令牌才能访问获取资源
    }
}

获取用户信息接口

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/getUser")
    public Object getUser(){
        return "成功获取到资源";// 给第三方网站返回用户信息(三方登入)
    }
}

配置用户登入信息

@Service
public class UserService implements UserDetailsService {
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 模拟根据username进行DB查询结果设置用户
        String password = passwordEncoder.encode("123");
        // 设置用户的账号、密码(security根据表单提交的登入信息进行比对)
        return new User("admin",password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

配置不需要登入认证才可访问的接口(如登入、退出登入接口) 

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login/**","/logout/**")
                .permitAll() // 以上接口允许不用授权服务
                .anyRequest()
                .authenticated() // 其它接口需要授权
                .and()
                .formLogin()
                .permitAll();
    }
}

配置好以上信息后就可以开始进行测试了

第一步:访问http://localhost:8080/oauth/authorize?client_id=admin&response_type=code获取授权码code,首次获取时我们需要先登入用户(就好比如果手机微信不登入怎么进行授权)

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_服务器_03

 登入成功后就会跳到这个页面(这个就是授权页面,就和微信询问你是否允许第三方应用登入一样)

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_spring_04

选择允许授权后,跳到百度页面,并且携带了授权码code

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_spring_05

接下来,我们就可以使用接口测试工具去获取令牌了(我使用的是Apifox)记得请求的端口要正确,下面截图中忘了写端口了。

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_spring_06

 

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_服务器_07

 发送请求后的返回体,access_token就是返回的令牌

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_spring_08

 接着携带令牌发送请求获取用户信息

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_服务器_09

 请求结果

spring设置了oauth2login后formlogin就不生效了吗 spring oauth2教程_服务器_10