公司新來了一個(gè)同事,把權(quán)限系統(tǒng)設(shè)計(jì)的爐火純青!
后臺(tái)回復(fù):1024,獲取海量學(xué)習(xí)資源
SQL刷題專欄
SQL145題系列
大家注意:
因?yàn)槲⑿鸥牧送扑蜋C(jī)制,會(huì)有小伙伴刷不到當(dāng)天的文章,
一些比較實(shí)用的知識(shí)和信息,錯(cuò)過了就是錯(cuò)過了。
所以建議大家加個(gè)星標(biāo)
,就能第一時(shí)間收到推送了。

-
角色互斥
-
基數(shù)約束
-
先決條件
-
運(yùn)行時(shí)互斥
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
package com.example.demo.web;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/test")public class Test {@RequestMapping("/test")public String test(){return "test";}}
用戶名:user密碼 984cccf2-ba82-468e-a404-7d32123d0f9c
spring:security:user:name: mingpassword: 123456roles: admin
package com.example.demo.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.crypto.password.NoOpPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;@Configurationpublic class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {@BeanPasswordEncoder passwordEncoder(){return NoOpPasswordEncoder.getInstance();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password("123").roles("admin");}}
package com.ming.demo.interceptor;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.HttpMethod;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.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;public class SecurityConfig extends WebSecurityConfigurerAdapter {//基于內(nèi)存的用戶存儲(chǔ)public void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("itguang").password("123456").roles("USER").and().withUser("admin").password("{noop}" + "123456").roles("ADMIN");}//請求攔截protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().permitAll().and().formLogin().permitAll().and().logout().permitAll();}}
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId><version>2.3.1.RELEASE</version></dependency>
package com.example.demo;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection;public class JwtUser implements UserDetails {private String username;private String password;private Integer state;private Collection<? extends GrantedAuthority> authorities;public JwtUser(){}public JwtUser(String username, String password, Integer state, Collection<? extends GrantedAuthority> authorities){this.username = username;this.password = password;this.state = state;this.authorities = authorities;}public Collection<? extends GrantedAuthority> getAuthorities() {return authorities;}public String getPassword() {return this.password;}public String getUsername() {return this.username;}public boolean isAccountNonExpired() {return true;}public boolean isAccountNonLocked() {return true;}public boolean isCredentialsNonExpired() {return true;}public boolean isEnabled() {return true;}}
package com.example.demo;import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import org.springframework.security.core.userdetails.UserDetails;import java.io.Serializable;import java.util.Date;import java.util.HashMap;import java.util.Map;public class JwtTokenUtil implements Serializable {private String secret;private Long expiration;private String header;private String generateToken(Map<String, Object> claims) {Date expirationDate = new Date(System.currentTimeMillis() + expiration);return Jwts.builder().setClaims(claims).setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, secret).compact();}private Claims getClaimsFromToken(String token) {Claims claims;try {claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();} catch (Exception e) {claims = null;}return claims;}public String generateToken(UserDetails userDetails) {Map<String, Object> claims = new HashMap<>(2);claims.put("sub", userDetails.getUsername());claims.put("created", new Date());return generateToken(claims);}public String getUsernameFromToken(String token) {String username;try {Claims claims = getClaimsFromToken(token);username = claims.getSubject();} catch (Exception e) {username = null;}return username;}public Boolean isTokenExpired(String token) {try {Claims claims = getClaimsFromToken(token);Date expiration = claims.getExpiration();return expiration.before(new Date());} catch (Exception e) {return false;}}public String refreshToken(String token) {String refreshedToken;try {Claims claims = getClaimsFromToken(token);claims.put("created", new Date());refreshedToken = generateToken(claims);} catch (Exception e) {refreshedToken = null;}return refreshedToken;}public Boolean validateToken(String token, UserDetails userDetails) {JwtUser user = (JwtUser) userDetails;String username = getUsernameFromToken(token);return (username.equals(user.getUsername()) && !isTokenExpired(token));}}
package com.example.demo;import org.apache.commons.lang.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;import org.springframework.stereotype.Component;import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {private UserDetailsService userDetailsService;private JwtTokenUtil jwtTokenUtil;protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {String authHeader = httpServletRequest.getHeader(jwtTokenUtil.getHeader());if (authHeader != null && StringUtils.isNotEmpty(authHeader)) {String username = jwtTokenUtil.getUsernameFromToken(authHeader);if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);if (jwtTokenUtil.validateToken(authHeader, userDetails)) {UsernamePasswordAuthenticationToken authentication =new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authentication);}}}filterChain.doFilter(httpServletRequest, httpServletResponse);}}
package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;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.Service;import javax.management.relation.Role;import java.util.List;public class JwtUserDetailsServiceImpl implements UserDetailsService {private UserMapper userMapper;public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {User user = userMapper.selectByUserName(s);if (user == null) {throw new UsernameNotFoundException(String.format("'%s'.這個(gè)用戶不存在", s));}List<SimpleGrantedAuthority> collect = user.getRoles().stream().map(Role::getRolename).map(SimpleGrantedAuthority::new).collect(Collectors.toList());return new JwtUser(user.getUsername(), user.getPassword(), user.getState(), collect);}}
public class UserServiceImpl implements UserService {private UserMapper userMapper;private AuthenticationManager authenticationManager;private UserDetailsService userDetailsService;private JwtTokenUtil jwtTokenUtil;public User findByUsername(String username) {User user = userMapper.selectByUserName(username);return user;}public RetResult login(String username, String password) throws AuthenticationException {UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password);final Authentication authentication = authenticationManager.authenticate(upToken);SecurityContextHolder.getContext().setAuthentication(authentication);UserDetails userDetails = userDetailsService.loadUserByUsername(username);return new RetResult(RetCode.SUCCESS.getCode(),jwtTokenUtil.generateToken(userDetails));}}
(prePostEnabled = true)public class WebSecurity extends WebSecurityConfigurerAdapter {private UserDetailsService userDetailsService;private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {authenticationManagerBuilder.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder());}(name = BeanIds.AUTHENTICATION_MANAGER)public AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}protected void configure(HttpSecurity http) throws Exception {http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll().antMatchers("/auth/**").permitAll().anyRequest().authenticated().and().headers().cacheControl();http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();registry.requestMatchers(CorsUtils::isPreFlightRequest).permitAll();}public CorsFilter corsFilter() {final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();final CorsConfiguration cors = new CorsConfiguration();cors.setAllowCredentials(true);cors.addAllowedOrigin("*");cors.addAllowedHeader("*");cors.addAllowedMethod("*");urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", cors);return new CorsFilter(urlBasedCorsConfigurationSource);}}
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {//attempt Authentication when Content-Type is jsonif(request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE)||request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)){//use jackson to deserialize jsonObjectMapper mapper = new ObjectMapper();UsernamePasswordAuthenticationToken authRequest = null;try (InputStream is = request.getInputStream()){AuthenticationBean authenticationBean = mapper.readValue(is,AuthenticationBean.class);authRequest = new UsernamePasswordAuthenticationToken(authenticationBean.getUsername(), authenticationBean.getPassword());}catch (IOException e) {e.printStackTrace();authRequest = new UsernamePasswordAuthenticationToken("", "");}finally {setDetails(request, authRequest);return this.getAuthenticationManager().authenticate(authRequest);}}//transmit it to UsernamePasswordAuthenticationFilterelse {return super.attemptAuthentication(request, response);}}}
protected void configure(HttpSecurity http) throws Exception {http.cors().and().antMatcher("/**").authorizeRequests().antMatchers("/", "/login**").permitAll().anyRequest().authenticated()//這里必須要寫formLogin(),不然原有的UsernamePasswordAuthenticationFilter不會(huì)出現(xiàn),也就無法配置我們重新的UsernamePasswordAuthenticationFilter.and().formLogin().loginPage("/").and().csrf().disable();//用重寫的Filter替換掉原有的UsernamePasswordAuthenticationFilterhttp.addFilterAt(customAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class);}//注冊自定義的UsernamePasswordAuthenticationFilterCustomAuthenticationFilter customAuthenticationFilter() throws Exception {CustomAuthenticationFilter filter = new CustomAuthenticationFilter();filter.setAuthenticationSuccessHandler(new SuccessHandler());filter.setAuthenticationFailureHandler(new FailureHandler());filter.setFilterProcessesUrl("/login/self");//這句很關(guān)鍵,重用WebSecurityConfigurerAdapter配置的AuthenticationManager,不然要自己組裝AuthenticationManagerfilter.setAuthenticationManager(authenticationManagerBean());return filter;}
/*** 密碼加密*/@Beanpublic BCryptPasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
public class UserServiceImpl implements UserService {private UserRepository userRepository;private BCryptPasswordEncoder bCryptPasswordEncoder; //注入bcryct加密public User add(User user) {user.setPassword(bCryptPasswordEncoder.encode(user.getPassword())); //對密碼進(jìn)行加密User user2 = userRepository.save(user);return user2;}public ResultInfo login(User user) {ResultInfo resultInfo=new ResultInfo();User user2 = userRepository.findByName(user.getName());if (user2==null) {resultInfo.setCode("-1");resultInfo.setMessage("用戶名不存在");return resultInfo;}//判斷密碼是否正確if (!bCryptPasswordEncoder.matches(user.getPassword(),user2.getPassword())) {resultInfo.setCode("-1");resultInfo.setMessage("密碼不正確");return resultInfo;}resultInfo.setMessage("登錄成功");return resultInfo;}}
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {private UserService userService; // service 層注入PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}protected void configure(AuthenticationManagerBuilder auth) throws Exception {// 參數(shù)傳入Service,進(jìn)行驗(yàn)證auth.userDetailsService(userService);}protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("admin").anyRequest().authenticated().and().formLogin().loginProcessingUrl("/login").permitAll().and().csrf().disable();}}
最后給大家分享我寫的SQL兩件套:《SQL基礎(chǔ)知識(shí)第二版》和《SQL高級(jí)知識(shí)第二版》的PDF電子版。里面有各個(gè)語法的解釋、大量的實(shí)例講解和批注等等,非常通俗易懂,方便大家跟著一起來實(shí)操。
有需要的讀者可以下載學(xué)習(xí),在下面的公眾號(hào)「數(shù)據(jù)前線」(非本號(hào))后臺(tái)回復(fù)關(guān)鍵字:SQL,就行
數(shù)據(jù)前線
后臺(tái)回復(fù)關(guān)鍵字:1024,獲取一份精心整理的技術(shù)干貨
后臺(tái)回復(fù)關(guān)鍵字:進(jìn)群,帶你進(jìn)入高手如云的交流群。
推薦閱讀
MySQL為啥不能用uuid做主鍵?!
97條 Linux 常用命令總結(jié)
“秒殺”問題的數(shù)據(jù)庫和SQL設(shè)計(jì)
MySQL:互聯(lián)網(wǎng)公司常用分庫分表方案匯總
掌握 SQL 這些核心知識(shí)點(diǎn),出去吹牛逼再也不擔(dān)心了 ![]()
評論
圖片
表情

