shiro簡單介紹
shiro是一個功能強大的java安全架構,主要部分構成認證、授權、加密和會話管理等。
1.認證:身份認證,驗證登入使用者是否正确等。
2.授權:授予權利通路某個頁面或接口。
3.加密:shiro提供加密服務。保護資料的安全性,如密碼加密存儲到資料庫,而不是明文存儲。
4.會話管理:使用者登入了一次就是會話,在一定時間内,使用者的所有資訊都儲存在會話中。
spring裝配shiro,基于javaBean的寫法
1.将SecurityManager交給spring處理
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
return securityManager;
}
2.建立realm
@Bean
public ShiroRealm shiroRealm(){
ShiroRealm shiroRealm=new ShiroRealm();
return shiroRealm;
}
3.配置ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
System.out.println("---shiroFIlter---");
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
//注意過濾器配置順序 不能颠倒
//配置退出 過濾器,其中的具體的退出代碼Shiro已經替我們實作了,登出後跳轉配置的loginUrl
// 配置不會被攔截的連結 順序判斷
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/favicon.ico", "anon");
//攔截其他是以接口
filterChainDefinitionMap.put("/**", "authc");
//配置shiro預設登入界面位址,前後端分離中登入界面跳轉應由前端路由控制,背景僅傳回json資料
shiroFilterFactoryBean.setLoginUrl("/login");
// 登入成功後要跳轉的連結 自行處理。不用shiro進行跳轉
// shiroFilterFactoryBean.setSuccessUrl("user/index");
//未授權界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/user/unauth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
4.建立代理bean通知類和開起shiro aop切面程式設計支援,注:往spring裡面注入這兩個bean。才能用注解的方式去對權限做校驗。
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
/**
* 開啟shiro aop注解支援
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor sourceAdvisor=new AuthorizationAttributeSourceAdvisor();
sourceAdvisor.setSecurityManager(securityManager);
return sourceAdvisor;
}
自定義實作realm,實作認證和授權的過程
1.認證過程
認證我們需要做的是通過使用者名的比對。從資料庫中查詢相應的使用者。并放入SimpleAuthenticationInfo中,剩下的交給shiro去認證校驗。
myrealm的認證:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String username = (String)authenticationToken.getPrincipal();
System.out.println(username);
ShiroUser shiroUser=shiroUserMapper.selectByUserName(username);
if (shiroUser==null){
return null;
}
SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(
shiroUser,
shiroUser.getPassword(),
getName()
);
return authenticationInfo;
}
}
查詢語句:
<select id="selectByUserName" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from shiro_user
where username = #{userName,jdbcType=VARCHAR}
</select>
2.授權過程
授權需要我們做的是通過使用者id查詢角色和權限,将權限和角色注入到AuthorizationInfo
授權:
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("--權限注入--");
SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
ShiroUser shiroUser= (ShiroUser) principalCollection.getPrimaryPrincipal();
//注入角色權限
try {
List<ShiroRole> shiroRoles=shiroUserMapper.selectRoleByUser(shiroUser.getId());
for (ShiroRole s:shiroRoles){
simpleAuthorizationInfo.addRole(s.getRoleName());
}
List<ShiroFunction> shiroFunctions =shiroUserMapper.queryByUserId(shiroUser.getId());
for(ShiroFunction functions:shiroFunctions){
simpleAuthorizationInfo.addStringPermission(functions.getPermissionName());
}
}catch (Exception e){
e.printStackTrace();
}
return simpleAuthorizationInfo;
}
查詢語句:
<select id="selectRoleByUser" parameterType="java.lang.Integer" resultType="com.example.pojo.ShiroRole">
select role_name,role_id,shiro_role.create_time
from shiro_role
left join shiro_user_role r on shiro_role.id = r.role_id
left join shiro_user u on r.user_id = u.id
where u.id=#{id,jdbcType=INTEGER}
</select>
<select id="queryByUserId" parameterType="java.lang.Integer" resultType="com.example.pojo.ShiroFunction">
select shiro_function.id,shiro_function.create_time,shiro_function.function_name,shiro_function.permission_name,shiro_function.pid
from shiro_function
left join shiro_role_function r on shiro_function.id = r.function_id
left join shiro_user_role u on u.role_id = r.role_id
left join shiro_user su on u.user_id = su.id
where su.id=#{id,jdbcType=INTEGER}
</select>
結語:
這樣一個簡單的shiro權限的配置和注入就完成了,基本能夠控制使用者登入,根據使用者的不用配置設定不同的權限和角色,達到對權限的控制。
demo位址:http://114.115.154.147/ 使用者名:admin 密碼:123 原諒沒有域名。