日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

spring-security登录和权限管理

發布時間:2024/9/27 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring-security登录和权限管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

spring security

spring security 主要的兩個功能是認證和授權
認證的大概流程:
Username password AuthenticationFilter(自定義usernamepassword攔截器)
UserDetailService (查詢用戶密碼的service接口)
Userdetails (用戶類接口)
AuthenticationProvide (為認證管理器AuthenticationManager 提供驗證組件AuthenticationProvider)
授權的大概流程:
(extends)AbstractsecurityInterceptor +(implements)Filter(資源訪問過濾器,攔截訪問請求,封裝成安全對象FilterInvocation,調用前兩個實例進行鑒權)
FilterInvocationSecurityMetadataSource(自定義權限數據源,提供所有URL資源與對應角色權限的映射集合)
AccessDecisionManager (自定義鑒權管理器,根據URL資源權限和用戶角色權限進行鑒權)

用戶登陸
會被AuthenticationProcessingFilter攔截,調用AuthenticationManager的實現,而且AuthenticationManager會調用ProviderManager來獲取用戶驗證信息(不同的Provider調用的服務不同,因為這些信息可以是在數據庫上,可以是在LDAP服務器上,可以是xml配置文件上等),如果驗證通過后會將用戶的權限信息封裝一個User放到spring的全局緩存SecurityContextHolder中,以備后面訪問資源時使用。
訪問資源(即授權管理
訪問url時,會通過AbstractSecurityInterceptor攔截器攔截,其中會調用FilterInvocationSecurityMetadataSource的方法來獲取被攔截url所需的全部權限,在調用授權管理器AccessDecisionManager,這個授權管理器會通過spring的全局緩存SecurityContextHolder獲取用戶的權限信息,還會獲取被攔截的url和被攔截url所需的全部權限,然后根據所配的策略(有:一票決定,一票否定,少數服從多數等),如果權限足夠,則返回,權限不夠則報錯并調用權限不足頁面。

項目結構:

數據庫設計:

model:
Permission

package com.example.arcgisdemo.model;import com.sun.javafx.beans.IDProperty;import javax.persistence.*; import java.util.List;@Entity @Table(name = "SYS_PERMISSION") public class Permission {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "ID")private int id;@Column(name = "NAME")private String name;@Column(name = "DESCRIPTION")private String description;@Column(name = "URL")private String url;@Column(name = "PID")private String pid;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getPid() {return pid;}public void setPid(String pid) {this.pid = pid;}}

User:
這里是在User中實現了UserDetails

package com.example.arcgisdemo.model;import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails;import javax.persistence.*; import java.util.ArrayList; import java.util.Collection; import java.util.List;@Entity @Table(name = "SYS_USER") public class User implements UserDetails {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "ID")private int id;@Column(name = "USERNAME")private String username;@Column(name = "PASSWORD")private String password;@ManyToMany(fetch = FetchType.EAGER)@JoinTable(name = "SYS_ROLE_USER",joinColumns = {@JoinColumn(name = "SYS_USER_ID",referencedColumnName = "ID")},inverseJoinColumns = {@JoinColumn(name = "SYS_ROLE_ID",referencedColumnName = "ID")})private List<Role> roles;@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {if (roles == null || roles.size() < 1) {return AuthorityUtils.commaSeparatedStringToAuthorityList("");}StringBuilder rolestring = new StringBuilder();for (Role role : roles) {rolestring.append(role.getName()).append(",");}List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList(rolestring.substring(0, rolestring.length() - 1));return authorityList;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}public List<Role> getRoles() {return roles;}public void setRoles(List<Role> roles) {this.roles = roles;}}

Role

package com.example.arcgisdemo.model;import javax.persistence.*; import java.util.List;@Entity @Table(name = "SYS_ROLE") public class Role {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "ID")private int id;@Column(name = "NAME")private String name;@ManyToMany(fetch = FetchType.EAGER)@JoinTable(name = "SYS_PERMISSION_ROLE",joinColumns = {@JoinColumn(name = "ROLE_ID",referencedColumnName = "ID")},inverseJoinColumns = {@JoinColumn(name = "PERMISSION_ID",referencedColumnName = "ID")})private List<Permission> permissions;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Permission> getPermissions() {return permissions;}public void setPermissions(List<Permission> permissions) {this.permissions = permissions;} }

security:
WebSecurityConfig 配置

package com.example.arcgisdemo.security;import com.example.arcgisdemo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; 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.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.password.NoOpPasswordEncoder; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;@Configuration @EnableWebSecurity //注解開啟Spring Security的功能 @EnableGlobalMethodSecurity(prePostEnabled = true) //開啟Spring Security注解功能 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserService userService;@Autowiredprivate SysFilterSecurityInterceptor sysFilterSecurityInterceptor;protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); // auth.authenticationProvider(new SysDaoAuthenticationProvider());}protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/js/layui/**").permitAll() //定義不需要認證就可以訪問的資源.anyRequest().authenticated().and().formLogin().loginPage("/login") //定義當需要用戶登錄時候,轉到的登錄頁面.loginProcessingUrl("/login").defaultSuccessUrl("/", true).failureUrl("/login?error").permitAll().and().logout().logoutUrl("/logout")//退出登錄后的默認Url是login.logoutSuccessUrl("/login").permitAll();//解決非thymeleaf的form表單提交被攔截問題http.csrf().disable();http.addFilter(customUsernamePasswordAuthenticationFilter());http.addFilterBefore(sysFilterSecurityInterceptor, FilterSecurityInterceptor.class).csrf().disable();http.headers().frameOptions().sameOrigin();} /*,"https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Hydrography/Watershed173811/MapServer/1","https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Hydrography/Watershed173811/MapServer/0","http://192.168.101.4:8080/agapi/**"*/@Beanpublic static NoOpPasswordEncoder passwordEncoder() {return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();}@Beanpublic UserDetailsService systemUserService() {return new UserService();}@Beanpublic SysUsernamePasswordF customUsernamePasswordAuthenticationFilter() throws Exception {SysUsernamePasswordF customUsernamePasswordAuthenticationFilter = new SysUsernamePasswordF();customUsernamePasswordAuthenticationFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST"));customUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());customUsernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler());customUsernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler("/login?error"));return customUsernamePasswordAuthenticationFilter;} }

SysUsernamePasswordF

package com.example.arcgisdemo.security; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;public class SysUsernamePasswordF extends UsernamePasswordAuthenticationFilter {public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {if (!request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());} else {String username = this.obtainUsername(request);String password = this.obtainPassword(request);if (username == null) {username = "";}else {}if (password == null) {password = "";}else {}username = username.trim();UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);this.setDetails(request, authRequest);return this.getAuthenticationManager().authenticate(authRequest);}} }

SysUserDetailsService

package com.example.arcgisdemo.security;import ch.qos.logback.core.joran.conditional.ElseAction; import com.example.arcgisdemo.model.Permission;import com.example.arcgisdemo.model.User; import com.example.arcgisdemo.service.PermissionService; import com.example.arcgisdemo.service.SysUserService; import com.example.arcgisdemo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; 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 java.util.ArrayList; import java.util.List;public class SysUserDetailsService implements UserDetailsService {@Autowiredprivate SysUserService sysUserService;@Autowiredprivate PermissionService permissionService;@Overridepublic UserDetails loadUserByUsername(String username) {User user = sysUserService.findByUserName(username);if (user != null) {List<Permission> permissions = permissionService.findById(user.getId());List<GrantedAuthority> grantedAuthorities = new ArrayList<>();for (Permission permission : permissions) {if (permission != null && permission.getName() != null) {GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());//將此處權限信息添加到GrantedAuthority對象中,在后面進行全權限驗證時會使用GrantedAuthoritygrantedAuthorities.add(grantedAuthority);}}return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);}else {throw new UsernameNotFoundException("do not exist");}} }

SysInvocationSecurityMetadataSourceService

package com.example.arcgisdemo.security;import com.example.arcgisdemo.model.Permission; import com.example.arcgisdemo.service.PermissionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.stereotype.Service; import sun.security.krb5.Config;import javax.servlet.http.HttpServletRequest; import java.util.*;@Service public class SysInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {@Autowiredprivate PermissionService permissionService;private HashMap<String,Collection<ConfigAttribute>> map=null;//加載權限表中所有權限public void loadResourceDefine(){map=new HashMap<>();Collection<ConfigAttribute> array;ConfigAttribute cfg;List<Permission> permissions=permissionService.findAll();for (Permission permission:permissions){array=new ArrayList<>();cfg=new SecurityConfig(permission.getName());//此處指添加用戶的名字,其實可以添加更多權限信息。例如請求方法到ConfigAttributr的集合中array.add(cfg);//用權限的getUrl。作為map的key。用ConfigAttribute的集合作為valuemap.put(permission.getUrl(),array);}} //此方法是為了判定用戶請求的url是否在權限表中,如果在權限表中,則返回給decide()方法, // 用來判斷用戶是否有此權限,如果不在權限表中則放行@Overridepublic Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {if(map ==null)loadResourceDefine();//object中包含用戶請求的request信息HttpServletRequest request=((FilterInvocation)object).getHttpRequest();AntPathRequestMatcher matcher;String resUrl;for (Iterator<String> iter=map.keySet().iterator();iter.hasNext();){resUrl=iter.next();matcher=new AntPathRequestMatcher(resUrl);if (matcher.matches(request)){return map.get(resUrl);}}return null;}@Overridepublic Collection<ConfigAttribute> getAllConfigAttributes() {return null;}@Overridepublic boolean supports(Class<?> aClass) {return true;} }

SysFilterSecurityInterceptor

package com.example.arcgisdemo.security;import org.apache.catalina.connector.Request; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.web.FilterInvocation; import org.springframework.stereotype.Service; import javax.servlet.*;import javax.servlet.*; import java.io.IOException; @Service(value = "sysFilterSecurityInterceptor") public class SysFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {@Autowired@Qualifier(value = "sysInvocationSecurityMetadataSourceService")private SysInvocationSecurityMetadataSourceService sysInvocationSecurityMetadataSourceService;@Autowired@Qualifier(value = "sysAccessDecisionManager")public void setSysAccessDecisionManager(SysAccessDecisionManager sysAccessDecisionManager){super.setAccessDecisionManager(sysAccessDecisionManager);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {FilterInvocation fi=new FilterInvocation(servletRequest,servletResponse,filterChain);invoke(fi);}public void invoke(FilterInvocation fi)throws IOException,ServletException{//fi里面有一個被攔截的url//里面調用SysInvocationSecurityMetadataSource的getAttributes(Object object)這個方法獲取fi對應的所有權限//在調用SysAccessDecisionManager的decide方法來校驗用戶的權限是否足夠InterceptorStatusToken token=super.beforeInvocation(fi);try {//執行下一個攔截器fi.getChain().doFilter(fi.getRequest(),fi.getResponse());}finally {super.afterInvocation(token,null);}}@Overridepublic void destroy() {}@Overridepublic Class<?> getSecureObjectClass() {return FilterInvocation.class;}@Overridepublic SecurityMetadataSource obtainSecurityMetadataSource() {return this.sysInvocationSecurityMetadataSourceService;} }

SysAccessDecisionManager

package com.example.arcgisdemo.security;import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Service;import java.util.Collection; import java.util.Iterator; @Service(value = "sysAccessDecisionManager") public class SysAccessDecisionManager implements AccessDecisionManager {//decide方法是判定是否擁有權限的決策方法//authentication 是釋SysUserDetailsService中循環添加到GrantedAuthority對象中的權限信息集合//object 包含客戶端發起的請求的request信息。可轉換為HttpServlerRequest request=((FilterInvocation) object).getHttpRequest();//configAttributes 為InvocationSecurityMetadataSource的getAttributes(Object)這個方法返回的結果//此方法是為了判定用戶請求的url,是否在權限表中,如果在權限表中,則返回給decide方法,//用來判定用戶是否有此權限,如果不在權限表中則放行。@Overridepublic void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {if (null==configAttributes || configAttributes.size()<=0){return;}ConfigAttribute configAttribute;String needRole;for (Iterator<ConfigAttribute> iter=configAttributes.iterator();iter.hasNext();){configAttribute=iter.next();needRole=configAttribute.getAttribute();for (GrantedAuthority ga:authentication.getAuthorities()){if (needRole.trim().equals(ga.getAuthority())){return;}}}throw new AccessDeniedException("no right");}@Overridepublic boolean supports(ConfigAttribute configAttribute) {return true;}@Overridepublic boolean supports(Class<?> aClass) {return true;} }

Service:
PermissionService

package com.example.arcgisdemo.service;import com.example.arcgisdemo.dao.PermissionDao; import com.example.arcgisdemo.model.Permission; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service;import java.util.List;@Service(value = "permissionService") public class PermissionService {@Autowired@Qualifier(value = "permissionDao")private PermissionDao permissionDao;public List<Permission> findAll(){return permissionDao.findAll();}public List<Permission> findById(int id){return permissionDao.findById(id);} }

SysUserService

package com.example.arcgisdemo.service;import com.example.arcgisdemo.dao.UserMapper; import com.example.arcgisdemo.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service;import java.util.List;@Service(value = "sysUserService") public class SysUserService {@Autowired@Qualifier(value = "userMapper")private UserMapper userMapper;public User queryByUserName(String username) {return userMapper.queryByUsername(username);}public User findByUserName(String username){return userMapper.findByUsername(username);} }

UserService

package com.example.arcgisdemo.service;import com.example.arcgisdemo.model.User; 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; @Service(value = "userService") public class UserService implements UserDetailsService {@Autowiredprivate SysUserService systemUserService;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {//根據用戶名從數據庫查詢對應記錄User user=systemUserService.queryByUserName(s);if (user ==null){throw new UsernameNotFoundException("username is not exists");}System.out.println("username:"+user.getUsername()+",password:"+user.getPassword());return user;} }

dao:
PermissionDao

package com.example.arcgisdemo.dao;import com.example.arcgisdemo.model.Permission; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository;import java.util.List;@Repository(value = "permissionDao") public interface PermissionDao extends JpaRepository<Permission,Long> {List<Permission> findAll();List<Permission> findById(int id); }

UserMapper

package com.example.arcgisdemo.dao;import com.example.arcgisdemo.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository;import java.util.List;@Repository(value = "userMapper") public interface UserMapper extends JpaRepository<User,Long> {User queryByUsername(String username);User findByUsername(String username); }

controller

package com.example.arcgisdemo.controller;import org.springframework.security.access.annotation.Secured; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class DemoController {@RequestMapping("/login")public String login() {return "login";}@RequestMapping("/")public String index1() {return "index-ui";}/*@Secured({"ROLE_ADMIN"})*/@RequestMapping("/user")public String user(){return "user";}@RequestMapping("/map")public String map(){return "map";} }

也可以在頁面上設置權限,讓沒有權限的用戶看不到該功能

<div sec:authorize="hasRole('ADMIN')"><!--設置權限--><ul class="layui-nav layui-layout-left"><li class="layui-nav-item"><a href="">控制臺</a></li><li class="layui-nav-item"><a href="">管理</a></li><li class="layui-nav-item"><a href="/user">用戶</a></li><li class="layui-nav-item"><a href="javascript:;">其它系統</a><dl class="layui-nav-child"><dd><a href="">郵件管理</a></dd><dd><a href="">消息管理</a></dd><dd><a href="">授權管理</a></dd></dl></li></ul></div>

在這里遇到個問題 剛開始的時候沒有效果,經過找資料需要將spring 版本降到2.0.7以下
再加上:

<htmlxmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">

pom.xml 需要配置secutiry擴展包

<dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity4</artifactId><version>3.0.2.RELEASE</version></dependency>

參考文檔:鏈接:https://www.jianshu.com/p/bcbbf16610fb

總結

以上是生活随笔為你收集整理的spring-security登录和权限管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。