shiro整合spring mvc的應用
阿新 • • 發佈:2018-12-17
1.首先準備五張表,分別為 使用者表、角色表、許可權表、使用者角色表、角色許可權表
CREATE TABLE `sys_users` ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `username` varchar(100) DEFAULT NULL, `password` varchar(100) DEFAULT NULL, `salt` varchar(100) DEFAULT NULL, `locked` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `idx_sys_users_username` (`username`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; CREATE TABLE `sys_roles` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `role_name` varchar(100) DEFAULT NULL, `description` varchar(100) DEFAULT NULL, `available` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `idx_sys_roles_role` (`role_name`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; CREATE TABLE `sys_permissions` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `permission` varchar(100) DEFAULT NULL, `perm_url` varchar(100) DEFAULT NULL, `parent_id` int(11) DEFAULT NULL, `description` varchar(100) DEFAULT NULL, `available` tinyint(1) DEFAULT '0', `type` int(1) DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `idx_sys_permissions_permission` (`permission`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; CREATE TABLE `sys_users_roles` ( `user_id` bigint(20) NOT NULL DEFAULT '0', `role_id` bigint(20) NOT NULL DEFAULT '0', PRIMARY KEY (`user_id`,`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `sys_roles_permissions` ( `id` int(11) NOT NULL, `role_id` bigint(20) NOT NULL DEFAULT '0', `permission_id` bigint(20) NOT NULL DEFAULT '0', PRIMARY KEY (`role_id`,`permission_id`,`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.我做的這個專案不是maven專案,所以我需要匯入引入shiro的jar包,,如果你的專案是maven專案的話,可以引入maven依賴
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.2</version> </dependency>
3.分別建立使用者、角色以及許可權的實體
4、在web.xml新增過濾器,攔截所有的url請求
<!-- spring 提供的用於整合shiro的過濾器 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
5、定義和注入securityManager
<!-- 配置一個和web.xml中DelegatingFilterProxy同名的bean物件 ,當前物件(工廠)用於建立shiro框架提供的多個過濾器的-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入安全管理器物件 -->
<property name="securityManager" ref="securityManager"></property>
<!-- 注入登入的訪問URL -->
<property name="loginUrl" value="/login"></property>
<!-- 登入成功後的跳轉頁面 -->
<property name="successUrl" value="/index"></property>
<!-- 注入許可權不足提示頁面 -->
<property name="unauthorizedUrl" value="/unauthorizedUrl"></property>
<!-- URL攔截規則
1). anon 可以被匿名訪問
2). authc 必須認證(即登入)後才可能訪問的頁面
3).perms['']表示需要某個許可權
-->
<property name="filterChainDefinitions">
<value>
/css/** = anon
/js/** = anon
/images/** = anon
/validatecode.jsp* = anon
/login =anon
/login* = anon
/page_base_staff.action = perms["staff.query"]
/* = authc
</value>
</property>
</bean>
<!-- 註冊一個安全管理器物件 -->
<bean id="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realms" ref="shiroDbRealm"></property>
</bean>
<!-- 註冊自定義realm -->
<bean id="shiroDbRealm" class="cn.my.blog.shiro.ShiroDbRealm"></bean>
6、自定義Realm內容
public class ShiroDbRealm extends AuthorizingRealm{
@Autowired
private UserService userService;
/**
* 授權
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
User user = (User) principals.getPrimaryPrincipal();
List<Role> roleList = userService.findRolesByUserId(user.getId());
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
for(Role role : roleList){
info.addRole(role.getRoleName());
info.addStringPermissions(role.getPermList());
}
return info;
}
/**
* 認證
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token ;
String username = upToken.getUsername();
User user = userService.findUserByUsername(username);
if(username == null){
return null;
}else{
String dbPassword = user.getPassword();
AuthenticationInfo info = new SimpleAuthenticationInfo(user, dbPassword,this.getClass().getSimpleName());
return info;
}
}
}
7、使用shiro進行登入
@RequestMapping(method = RequestMethod.POST)
public String loginPost(HttpServletRequest req,Model model){
String message = "登入成功";
//獲取subject
Subject subject = SecurityUtils.getSubject();
String password = req.getParameter("password");
password = MD5Utils.md5(password);
AuthenticationToken token = new UsernamePasswordToken(req.getParameter("username"), password);
try{
//使用shiro進行登入,報錯及驗證不通過
subject.login(token);
User user = (User)subject.getPrincipal();
session.setAttribute("user", user);
}catch(UnknownAccountException e){
e.printStackTrace();
message="使用者名稱或密碼錯誤";
model.addAttribute("message",message);
return LOGIN;
}catch (Exception e) {
e.printStackTrace();
message="登入失敗";
model.addAttribute("message",message);
return LOGIN;
}
model.addAttribute("message",message);
return MAIN_INDEX;
}