zoukankan      html  css  js  c++  java
  • SpringBoot2.x版本整合SpringSecurity、Oauth2进行password认证

    很多人在进行项目开发时都会用到Oauth2.0结合SpringSecurity或者Shiro进行权限拦截以及用户验证,网上也有很多的案例,前几天项目里边需要用到,顺便整合了进来,特此写篇博客,记录下过程。

    项目结构如下:

    首先准备pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <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>
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.0.3.RELEASE</version>
    		<relativePath /> <!-- lookup parent from repository -->
    	</parent>
    	<groupId>com.xz.springcloud</groupId>
    	<artifactId>f-oauth2-pwd-mode</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>f-oauth2-pwd-mode</name>
    	<description>Demo project for Spring Boot</description>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    		<java.version>1.8</java.version>
    		<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    		<oauth.version>2.3.3.RELEASE</oauth.version>        
    	</properties>
    
    	<dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
           
            <dependency>
                <groupId>org.springframework.security.oauth</groupId>
                <artifactId>spring-security-oauth2</artifactId>
                <version>2.2.1.RELEASE</version>
            </dependency>
            
             <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
            
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
    	<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>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    </project>
    

    MyUserDetailService.java

    package com.oauth.config;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    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.stereotype.Component;
    
    /**
     * 
     * @author yuxuan
     *
     */
    @Component
    public class MyUserDetailsService implements UserDetailsService {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            // TODO 这个地方可以通过username从数据库获取正确的用户信息,包括密码和权限等。
            List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
            grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_USER"));
            grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
            return new User(username, "{noop}123456", grantedAuthorityList);
        }
    }
    

    OAuth2ServerConfig.java

    package com.oauth.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.authentication.AuthenticationManager;
    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;
    
    @Configuration
    @EnableAuthorizationServer
    public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
    
    	 @Override
    	    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    	        oauthServer
    	                .tokenKeyAccess("permitAll()") //url:/oauth/token_key,exposes public key for token verification if using JWT tokens
    	                .checkTokenAccess("isAuthenticated()") //url:/oauth/check_token allow check token
    	                .allowFormAuthenticationForClients();
    	    }
    	    
    	    /**
    	     * 注入authenticationManager
    	     * 来支持 password grant type
    	     */
    	    @Autowired
    	    private AuthenticationManager authenticationManager;
    
    	    @Override
    	    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    	        endpoints.authenticationManager(authenticationManager);
    	        endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    	    }
    
    	    @Override
    	    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    	        clients.inMemory()
    	                .withClient("client")
    	                .secret("{noop}secret")
    	                .authorizedGrantTypes("client_credentials", "password", "refresh_token")
    	                .scopes("all")
    	                .resourceIds("resourcesId")
    	                .accessTokenValiditySeconds(1200)
    	                .refreshTokenValiditySeconds(50000);
    	}
    	
    }
    

    ResourceServerConfig.java

    package com.oauth.config;
    
    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;
    import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
    
    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
    	@Override
    	public void configure(HttpSecurity http) throws Exception {
    		http.requestMatchers().antMatchers("/api/**").and().authorizeRequests().antMatchers("/api/**").authenticated();
    	}
    	
    	@Override
    	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    		resources.resourceId("resourcesId").stateless(true);
    	}
    	
    }
    

    WebConfig.java

    package com.oauth.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    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;
    
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
    public class WebConfig extends WebSecurityConfigurerAdapter {
    
    	 @Override
    	 protected void configure(HttpSecurity http) throws Exception {
    		 http.csrf().disable();
    	    http.requestMatchers().antMatchers("/oauth/**")
    	    .and()
    	    .authorizeRequests()
    	    .antMatchers("/oauth/**").authenticated();
    	 }
    
    
    	/**
    	 * 需要配置这个支持password模式 support password grant type
    	 * @return
    	 * @throws Exception
    	 */
    	@Override
    	@Bean
    	public AuthenticationManager authenticationManagerBean() throws Exception {
    		return super.authenticationManagerBean();
    	}
    
    }
    

    IndexCtrl.java

    package com.oauth.ctrl;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class IndexCtrl {
    
    	@GetMapping("hello")
    	public String hello() {
    		return "Hello World";
    	}
    	
    	@GetMapping("api/hello")
    	public String apiHello() {
    		return "Hello World";
    	}
    	
    }
    

    App.java

    package com.oauth;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class App {
    
    	public static void main(String[] args) {
    		SpringApplication.run(App.class, args);
    		
    	}
    }
    

    以上就是一个代码的配置,下面启动App类,运行main函数。项目启动完成后用rest client访问hello接口

    可以看到提示无效的token,接下我们请求获取token。利用CURL命令请求如下:

    curl -i -X POST -d "username=admin&password=123456&grant_type=password&client_id=client&client_secret=secret" http://localhost:8888/oauth/token

    可以看到,至此已经访问成功了。

    也可以利用GET方式直接访问,如下:

    http://localhost:8888/api/hello?access_token=cca911c0-532f-475b-83e6-3a2671a8fe07

    有问题可以在下面评论,技术问题可以私聊我。 

  • 相关阅读:
    侧滑界面的实现
    Private field 'XXX' is never assigned的解决办法
    android先加载注册页面而不是MainActivity主页面
    每日日报4
    每日日报3
    47 选择排序和插入排序
    计算机启动过程 BIOS MBR等
    ARM中MMU地址转换理解(转)
    深度学习框架 CatBoost 介绍
    预训练词嵌入
  • 原文地址:https://www.cnblogs.com/c1024/p/11011997.html
Copyright © 2011-2022 走看看