mysql table
CREATE TABLE `oauth_access_token` (
`token_id` varchar(256) DEFAULT NULL,
`token` blob,
`authentication_id` varchar(250) NOT NULL,
`user_name` varchar(256) DEFAULT NULL,
`client_id` varchar(256) DEFAULT NULL,
`authentication` blob,
`refresh_token` varchar(256) DEFAULT NULL,
PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
CREATE TABLE `oauth_client_details` (
`client_id` varchar(250) NOT NULL,
`resource_ids` varchar(256) DEFAULT NULL,
`client_secret` varchar(256) DEFAULT NULL,
`scope` varchar(256) DEFAULT NULL,
`authorized_grant_types` varchar(256) DEFAULT NULL,
`web_server_redirect_uri` varchar(256) DEFAULT NULL,
`authorities` varchar(256) DEFAULT NULL,
`access_token_validity` int(11) DEFAULT NULL,
`refresh_token_validity` int(11) DEFAULT NULL,
`additional_information` varchar(4096) DEFAULT NULL,
`autoapprove` varchar(256) DEFAULT NULL,
PRIMARY KEY (`client_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
CREATE TABLE `oauth_refresh_token` (
`token_id` varchar(256) DEFAULT NULL,
`token` blob,
`authentication` blob
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
--------------------------------------------------------------------------------------------------------

package com.tang.auth.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
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.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
@EnableAuthorizationServer
@Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter{
@Autowired
private DataSource dataSource;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore())
.userDetailsService(userDetailsService)
.authenticationManager(authenticationManager)
.setClientDetailsService(clientDetails());
//????TokenServices????
// DefaultTokenServices tokenServices = new DefaultTokenServices();
// tokenServices.setTokenStore(endpoints.getTokenStore());
// tokenServices.setSupportRefreshToken(true);
// tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
// tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
// // access_token ???????5s
// tokenServices.setAccessTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(1));
// // refresh_token ???????????????
//// tokenServices.setReuseRefreshToken(true);
//// tokenServices.setRefreshTokenValiditySeconds((int) TimeUnit.SECONDS.toSeconds(20));
//
// endpoints.tokenServices(tokenServices);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.tokenKeyAccess("permitAll()")
.checkTokenAccess("permitAll()")
.allowFormAuthenticationForClients();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource)
.withClient("client_id2")
.secret(new BCryptPasswordEncoder().encode("123456"))
.authorizedGrantTypes("password","refresh_token")
.scopes("select,read")
.resourceIds("rid")
.authorities("USER") //?查了一下感觉没什么用
.accessTokenValiditySeconds(60)
.refreshTokenValiditySeconds(1200);
}
//使用内存中的 token store
// return new InMemoryTokenStore();
//使用Jdbctoken store
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
/**
* 对 oauth_client_details 表的一些操作
*
* @return ClientDetailsService
*/
@Bean
public ClientDetailsService clientDetails() {
JdbcClientDetailsService service = new JdbcClientDetailsService(dataSource);
ClientDetails clientDetails;
try {
clientDetails = service.loadClientByClientId("client_id2");
} catch (Exception e) {
return service;
}
if(clientDetails != null) {
service.removeClientDetails("client_id2");//每次重启移除,防止主键冲突
}
return service;
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
-------------------------------------------------------------------------------------
package com.tang.auth.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;
@EnableResourceServer
@Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**")
.access("#oauth2.hasScope(‘read‘)") //oauth2 scope 是read,只能read申请的token才能访问
.anyRequest().authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("rid") //rid 必须跟 授权服务器配置的rID一样
.stateless(true); //必须有令牌才能访问?
}
}
-------------------------------------------------------------------------------------------
package com.tang.auth.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/oauth/**")
.permitAll()
.anyRequest()
.authenticated();
}
--------------------------------------------------------------------------------------------------
package com.tang.auth.controller;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoginController {
@GetMapping("login")
public String login() {
return "success";
}
@PostMapping("logon")
//@PreAuthorize("hasAuthority(‘USER‘)") 如果添加 role 要是USER, 如果不是scope正确也不能访问
public String logon() {
return "success";
}
@PostMapping("logon2")
@PreAuthorize("#oauth2.hasScope(‘write‘)") //配置oauth 的scope范围
public String logon2() {
return "success";
}
}
------------------------------------------------------------------------------------
import org.springframework.data.jpa.repository.JpaRepository;
import com.tang.auth.bean.User;
public interface UserDao extends JpaRepository<User, Integer>{
public User queryByUsername(String username);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
------------------------------------------------------------------------------------------------------
package com.tang.auth.service;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
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.tang.auth.bean.User;
import com.tang.auth.dao.UserDao;
@Service
public class UserService implements UserDetailsService {
@Autowired
private UserDao userDao;
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User user = userDao.queryByUsername(name);
System.out.println("1111111111111");
UserDetails userDetails = null;
if (Optional.ofNullable(user).isPresent()) {
return new org.springframework.security.core.userdetails.User(name, user.getPassword(), true, true, true, true,
user.getAuthorities());
}
return userDetails;
}
}
----------------------------------------------------------------------------
package com.tang.auth.bean;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import lombok.Data;
@Data
@Entity
public class User implements UserDetails {
@Id
@GeneratedValue
private Integer id;
@Column(name = "name")
private String username;
private String password;
private String role;
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> list = new ArrayList();
list.add(new SimpleGrantedAuthority("ROLE_" + this.role));
return list;
}
public boolean isAccountNonExpired() {
return false;
}
public boolean isAccountNonLocked() {
return false;
}
public boolean isCredentialsNonExpired() {
return false;
}
public boolean isEnabled() {
return false;
}
}
---------------------------------------------------------------------------------------------------
server.port=60001
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
http://localhost:60001/oauth/token?grant_type=password&client_id=client_id2&client_secret=123456&username=admin&password=admin&scope=read


springboot spring security oauth2 password 模式
原文:https://www.cnblogs.com/tangfeifei2020/p/13093455.html