自定义Realm
自定义Realm类
import com.shiro.entity.User;
import com.shiro.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 用户自定义Realm
*/
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 授权:为当前登录的用户授予权限及角色
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//1、获取当前登录的用户信息
String userName = (String) principals.getPrimaryPrincipal();
//2、创建授权验证对象
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
try {
//3、授予角色
authorizationInfo.setRoles(userService.getRoles(userName));
//4、授予权限
authorizationInfo.setStringPermissions(userService.getPermissions(userName));
} catch (Exception e) {
e.printStackTrace();
}
//5、返回授权信息
return authorizationInfo;
}
/**
* 验证:为当前登录的用户进行身份验证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//从token中获取当前用户信息
String userName = (String) token.getPrincipal();
//和(String) token.getPrincipal()一样的效果
//UsernamePasswordToken token1=(UsernamePasswordToken)token;
//String userName=token1.getUsername();
try {
//根据用户名查询用户信息
User user = userService.findUserByName(userName);
//如果结果不为空,表示这个用户是存在的
if (user != null) {
//验证用户名和密码,存的是数据库查到的信息
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), "");
//返回验证信息
return authenticationInfo;
}
} catch (Exception e) {
e.printStackTrace();
}
//验证失败
return null;
}
}
Realm类注入到securityManager安全管理器
//securityManager安全管理器
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
//自定义的realm类
<property name="realm" ref="myRealm"/>
//凭证匹配器
<property name="realms">
<list>
<ref bean="jdbcRealm"/>
</list>
</property>
</bean>
shiro加密
不配置的话是没有加密的,如果配置了凭证器,可以进行加密码操作,以下是加密的配置
配置凭证器
<!-- 凭证匹配器,用来做密码加密 -->
<bean id="jdbcRealm" class="com.shiro.realm.UserRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!--加密方式,MD5-->
<property name="hashAlgorithmName" value="MD5"></property>
<!--加密次数,加密次数不一样,值不一样-->
<property name="hashIterations" value="1024"></property>
</bean>
</property>
</bean>
注入到securityManager
//securityManager安全管理器
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
//自定义的realm类
<property name="realm" ref="myRealm"/>
//凭证匹配器
<property name="realms">
<list>
<ref bean="jdbcRealm"/>
</list>
</property>
</bean>
盐值加密
两个相同的值加密的结果是一样的,避免这种情况,可以增加盐值,让加密结果不一样。
修改realm类,加入盐值
//验证用户名和密码,不加盐值
//AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), "");
//盐值,这里userName是用户名,用用户名作为盐值,也可以用其他值
ByteSource credentialsSalt = ByteSource.Util.bytes(userName);
//验证用户名和密码,加了盐值
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user.getUserName(), user.getPassword(),credentialsSalt, "");
shiro标签
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
用户名
//显示用户名
<shiro:principal></shiro:principal>
登录的用户有admin这个角色才能看到
<shiro:hasRole name="admin">
<br/>
<a href="admin.jsp">有admin权限,Admin</a>
</shiro:hasRole>