针对以上来做各种变通分析权限控制的需求
表设计:
使用技术
表的使用
对不同用户分配角色
相关问题
要是一个销售员除了有soler角色外还有一些其他权限怎么办呢?比如销售员还有部分采购员一部分权限
这种情况可以采用量两种方式解决这个问题:
创建一个新角色(比如soler2)来包含原本soler角色里面的所有权限和新拥有的权限
创建一个新角色,仅包含新拥有权限即可,然后设置该新角色的父级为soler角色,形成从属关系
还有没有其他特殊情况没考虑进来的吗?
使用拦截器实现
在spring配置文件中添加拦截器配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="li" class="cn.util.LoginIntercepter" >bean>
mvc:interceptor>
mvc:interceptors>
2.拦截器处理权限类
public class LoginIntercepter extends HandlerInterceptorAdapter {
private static String [] urls = {"uc/checklogin"};
public static boolean checkUrl(String requestname){
//筛选静态资源
if(requestname==null||requestname.equals("")){
return true;
} if(requestname.endsWith(".js")||requestname.endsWith(".css")||requestname.endsWith(".jpg")){
return true;
}
for (int i = 0; i < urls.length; i++) {
if(urls[i].equals(requestname)){
return true;
}
}
return false;
}
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//1.登录拦截
//2.权限验证,验证当前用户是否拥有当前请求这个权限
HttpSession session = request.getSession();
//获取当前请求的名字
String uri = request.getRequestURI();
String contextpath = request.getContextPath();
String requestname = uri.substring(contextpath.length()+1, uri.length());
//动态获取项目的网络地址
String basepath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+contextpath+"/";
if(checkUrl(requestname)){
return true;
}
//验证用户是否登录
Object obj = session.getAttribute("users");
if(obj==null){
response.sendRedirect(basepath+"index.jsp");
return false;
}
//某些请求(比如修改自己的基本信息,退出登录...),是只要求登录就可以访问,而没有纳入权限管理范围的
//对于这部分请求,应该只做登录验证,而不进入权限验证范围
ServletContext application = session.getServletContext();
List allurl = (List) application.getAttribute("allurl");
if(!allurl.contains(requestname)){
return true;
}
//如果程序执行到这里,用户已经登录,并且当前请求不是请求的静态资源
//所以这里需要开始权限判断,判断当前用户是否拥有当前请求的权限
Users users = (Users) obj;
if(users.getRole()==null){
response.sendRedirect(basepath+"nopriviliage.jsp");
return false;
}
//得到当前用户所拥有的的所有权限信息
List prilist = users.getRole().getPrilist();
if(!checkpri(prilist, requestname)){
response.sendRedirect(basepath+"nopriviliage.jsp");
return false;
}
return true;
}
public static boolean checkpri(List prilist,String requestname){
for (int i = 0; i < prilist.size(); i++) {
Priviliage pri = prilist.get(i);
if(pri.getPriUrl()!=null&&pri.getPriUrl().equals(requestname)){
return true;
}
}
return false;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
使用shiro安全框架实现
导入shiro支持包jar包
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-coreartifactId>
<version>1.2.5version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-webartifactId>
<version>1.2.5version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-springartifactId>
<version>1.2.5version>
dependency>
<dependency>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${slf4j.version}version>
dependency>
2.在web.xml下配置过滤器
<filter>
<filter-name>shiroFilterfilter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
<init-param>
<param-name>targetFilterLifecycleparam-name>
<param-value>trueparam-value>
init-param>
<init-param>
<param-name>targetBeanNameparam-name>
<param-value>shiroFilterparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>shiroFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
3.在spring配置文件中配置shiro支持(这里使用自定义realm)
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login.action" />
<property name="successUrl" value="/first.action"/>
<property name="unauthorizedUrl" value="/refuse.jsp" />
<property name="filterChainDefinitions">
<value>
/images/**=anon
/js/**=anon
/style/**=anon
/**=anon
value>
property>
bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm" />
bean>
<bean id="myRealm" class="com.lumingshan.web.utils.MyRealm">
bean>
4.自定义realm类
public class MyRealm extends AuthorizingRealm {
@Resource(name = "roleServiceImpl")
private RoleService roleServiceImpl;
@Resource(name = "userServiceImpl")
private UserService userServiceImpl;
@Resource(name = "authServiceImpl")
private AuthService authServiceImpl;
// 为当前登陆成功的用户授予权限和角色,已经登陆成功了
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal(); //获取用户名
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
User loginUser = new User();
loginUser.setUsername(username);
User user = userServiceImpl.login(loginUser);
Role role = roleServiceImpl.getRoleByRoleId(user.getRole().getRoleId());
//装成set集合
HashSet roleSet = new HashSet<>();
roleSet.add(role.getEnName());
authorizationInfo.setRoles(roleSet);
List authList = authServiceImpl.getAuthByRoleId(role.getRoleId());
HashSet authSet = new HashSet<>();
for (Auth auth : authList) {
authSet.add(auth.getEnName());
}
authorizationInfo.setStringPermissions(authSet);
return authorizationInfo;
}
// 验证当前登录的用户,获取认证信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal(); // 获取用户名
User loginUsers = new User();
loginUsers.setUsername(username);
User user = userServiceImpl.login(loginUsers);
if(user != null) {
//此步验证密码
AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getUserpwd(), "myRealm");
return authcInfo;
} else {
return null;
}
}
}
5.controller调用realm
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("login")
@ResponseBody
public Object login(@RequestBody User user,HttpServletRequest request) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getUserpwd());
try{
subject.login(token);//跳到自定义的realm中
request.getSession().setAttribute("user", user);
return new Result<>(null);
}catch(Exception e){
e.printStackTrace();
return new Result<>(0,null);
}
}
}