Commit 819ab9e3 authored by 杨伊博's avatar 杨伊博

permission manage is ok

parent 36177186
package com.us.example.config; package com.us.example.config;
import com.us.example.security.CustomUserService; import com.us.example.service.CustomUserService;
import com.us.example.service.MyFilterSecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
/** /**
* Created by yangyibo on 17/1/18. * Created by yangyibo on 17/1/18.
*/ */
@Configuration @Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean @Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
@Bean
UserDetailsService customUserService(){ //注册UserDetailsService 的bean UserDetailsService customUserService(){ //注册UserDetailsService 的bean
return new CustomUserService(); return new CustomUserService();
} }
...@@ -35,6 +46,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -35,6 +46,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.permitAll() //登录页面用户任意访问 .permitAll() //登录页面用户任意访问
.and() .and()
.logout().permitAll(); //注销行为任意访问 .logout().permitAll(); //注销行为任意访问
http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
} }
......
...@@ -4,6 +4,7 @@ import com.us.example.domain.Msg; ...@@ -4,6 +4,7 @@ import com.us.example.domain.Msg;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/** /**
* Created by yangyibo on 17/1/18. * Created by yangyibo on 17/1/18.
...@@ -13,8 +14,15 @@ public class HomeController { ...@@ -13,8 +14,15 @@ public class HomeController {
@RequestMapping("/") @RequestMapping("/")
public String index(Model model){ public String index(Model model){
Msg msg = new Msg("测试标题","测试内容","额外信息,只对管理员显示"); Msg msg = new Msg("测试标题","测试内容","欢迎来到HOME页面,您拥有 ROLE_HOME 权限");
model.addAttribute("msg", msg); model.addAttribute("msg", msg);
return "home"; return "home";
} }
@RequestMapping("/admin")
@ResponseBody
public String hello(){
return "hello admin";
}
} }
package com.us.example.dao;
import com.us.example.config.MyBatisRepository;
import com.us.example.domain.Permission;
import java.util.List;
/**
* Created by yangyibo on 17/1/20.
*/
@MyBatisRepository
public interface PermissionDao {
public List<Permission> findAll();
public List<Permission> findByAdminUserId(int userId);
}
package com.us.example.domain;
/**
* Created by yangyibo on 17/1/20.
*/
public class Permission {
private int id;
//权限名称
private String name;
//权限描述
private String descritpion;
//授权链接
private String url;
//父节点id
private int 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 getDescritpion() {
return descritpion;
}
public void setDescritpion(String descritpion) {
this.descritpion = descritpion;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
}
package com.us.example.security; package com.us.example.service;
import com.us.example.dao.PermissionDao;
import com.us.example.dao.UserDao; import com.us.example.dao.UserDao;
import com.us.example.domain.Permission;
import com.us.example.domain.SysRole; import com.us.example.domain.SysRole;
import com.us.example.domain.SysUser; import com.us.example.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired; 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.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
...@@ -21,24 +25,44 @@ public class CustomUserService implements UserDetailsService { //自定义UserDe ...@@ -21,24 +25,44 @@ public class CustomUserService implements UserDetailsService { //自定义UserDe
@Autowired @Autowired
UserDao userDao; UserDao userDao;
@Autowired
PermissionDao permissionDao;
@Override // @Override
public UserDetails loadUserByUsername(String username) { //重写loadUserByUsername 方法获得 userdetails 类型用户 // public UserDetails loadUserByUsername(String username) { //重写loadUserByUsername 方法获得 userdetails 类型用户
//
// SysUser user = userDao.findByUserName(username);
// if(user == null){
// throw new UsernameNotFoundException("用户名不存在");
// }
// List<SimpleGrantedAuthority> authorities = new ArrayList<>();
// //用于添加用户的权限。只要把用户权限添加到authorities 就万事大吉。
// for(SysRole role:user.getRoles())
// {
// authorities.add(new SimpleGrantedAuthority(role.getName()));
// System.out.println(role.getName());
// }
// return new org.springframework.security.core.userdetails.User(user.getUsername(),
// user.getPassword(), authorities);
//
// }
public UserDetails loadUserByUsername(String username) {
SysUser user = userDao.findByUserName(username); SysUser user = userDao.findByUserName(username);
if(user == null){ if (user != null) {
throw new UsernameNotFoundException("用户名不存在"); List<Permission> permissions = permissionDao.findByAdminUserId(user.getId());
} List<GrantedAuthority> grantedAuthorities = new ArrayList <>();
List<SimpleGrantedAuthority> authorities = new ArrayList<>(); for (Permission permission : permissions) {
//用于添加用户的权限。只要把用户权限添加到authorities 就万事大吉。 if (permission != null && permission.getName()!=null) {
for(SysRole role:user.getRoles())
{
authorities.add(new SimpleGrantedAuthority(role.getName()));
System.out.println(role.getName());
}
return new org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(), authorities);
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
grantedAuthorities.add(grantedAuthority);
}
}
return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
} else {
throw new UsernameNotFoundException("admin: " + username + " do not exist!");
}
} }
} }
package com.us.example.service;
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;
/**
* Created by yangyibo on 17/1/19.
*/
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
if(null== configAttributes || configAttributes.size() <=0) {
return;
}
ConfigAttribute c;
String needRole;
for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {
c = iter.next();
needRole = c.getAttribute();
for(GrantedAuthority ga : authentication.getAuthorities()) {
if(needRole.trim().equals(ga.getAuthority())) {
return;
}
}
}
throw new AccessDeniedException("no right");
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}
package com.us.example.service;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
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.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;
import java.io.IOException;
/**
* Created by yangyibo on 17/1/19.
*/
@Service
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
@Autowired
private FilterInvocationSecurityMetadataSource securityMetadataSource;
@Autowired
public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
super.setAccessDecisionManager(myAccessDecisionManager);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
public void invoke(FilterInvocation fi) throws IOException, ServletException {
//fi里面有一个被拦截的url
//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限
//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
//执行下一个拦截器
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
@Override
public void destroy() {
}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
}
package com.us.example.service;
import com.us.example.dao.PermissionDao;
import com.us.example.domain.Permission;
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 javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* Created by yangyibo on 17/1/19.
*/
@Service
public class MyInvocationSecurityMetadataSourceService implements
FilterInvocationSecurityMetadataSource {
@Autowired
private PermissionDao permissionDao;
private HashMap<String, Collection<ConfigAttribute>> map =null;
/**
* 加载资源,初始化资源变量
*/
public void loadResourceDefine(){
map = new HashMap<>();
Collection<ConfigAttribute> array;
ConfigAttribute cfg;
List<Permission> permissions = permissionDao.findAll();
for(Permission permission : permissions) {
array = new ArrayList<>();
cfg = new SecurityConfig(permission.getName());
array.add(cfg);
map.put(permission.getUrl(), array);
}
}
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
if(map ==null) loadResourceDefine();
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;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.us.example.dao.PermissionDao">
<select id="findAll" resultType="com.us.example.domain.Permission">
SELECT * from Sys_permission ;
</select>
<select id="findByAdminUserId" parameterType="int" resultType="com.us.example.domain.Permission">
select p.*
from Sys_User u
LEFT JOIN sys_role_user sru on u.id= sru.Sys_User_id
LEFT JOIN Sys_Role r on sru.Sys_Role_id=r.id
LEFT JOIN Sys_permission_role spr on spr.role_id=r.id
LEFT JOIN Sys_permission p on p.id =spr.permission_id
where u.id=#{userId}
</select>
</mapper>
\ No newline at end of file
...@@ -24,6 +24,7 @@ body { ...@@ -24,6 +24,7 @@ body {
<div id="navbar" class="collapse navbar-collapse"> <div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a th:href="@{/}"> 首页 </a></li> <li><a th:href="@{/}"> 首页 </a></li>
<li><a th:href="@{/admin}"> admin </a></li>
</ul> </ul>
</div><!--/.nav-collapse --> </div><!--/.nav-collapse -->
</div> </div>
...@@ -37,15 +38,14 @@ body { ...@@ -37,15 +38,14 @@ body {
<p class="bg-primary" th:text="${msg.content}"></p> <p class="bg-primary" th:text="${msg.content}"></p>
<div sec:authorize="hasRole('ROLE_ADMIN')"> <!-- 用户类型为ROLE_ADMIN 显示 --> <div sec:authorize="hasRole('ROLE_HOME')"> <!-- 用户类型为ROLE_ADMIN 显示 -->
<p class="bg-info" th:text="${msg.etraInfo}"></p> <p class="bg-info" th:text="${msg.etraInfo}"></p>
</div> </div>
<div sec:authorize="hasRole('ROLE_ADMIN')"> <!-- 用户类型为ROLE_ADMIN 显示 -->
<div sec:authorize="hasRole('ROLE_USER')"> <!-- 用户类型为 ROLE_USER 显示 --> <p class="bg-info">恭喜您,您有 ROLE_ADMIN 权限 </p>
<p class="bg-info">无更多信息显示</p> </div>
</div>
<form th:action="@{/logout}" method="post">
<form th:action="@{/logout}" method="post">
<input type="submit" class="btn btn-primary" value="注销"/> <input type="submit" class="btn btn-primary" value="注销"/>
</form> </form>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment