shiro的java代码,shirodkar

如何正确的使用shiro

从来没接触过shiro Java安全框架,突然有一天需要要用用户登陆验证和用户角色权限的任务,而且是针对shiro 进行整合,开始收到任务,心都有点凉凉的。经过一轮的搜索,感觉没多大的收获。很多用户的角色都是写在xml配置文件中。觉得太不人性化了,想换个用户角色还得改xml?我觉得这么强大的框架应该不可能这么狗血的存在。然后认真的看文档,发现真的是可以直接读取数据库的。我把我搭建的流程发布在此。有问题的可以交流交流。我写的也并不是正确的,只能参考参考。

创新互联建站技术团队10年来致力于为客户提供成都网站设计、成都网站建设、外贸网站建设品牌网站建设成都全网营销、搜索引擎SEO优化等服务。经过多年发展,公司拥有经验丰富的技术团队,先后服务、推广了近千家网站,包括各类中小企业、企事单位、高校等机构单位。

1.web.xml的配置

listener

listener-classorg.apache.shiro.web.env.EnvironmentLoaderListener/listener-class

/listener

filter

filter-nameshiroFilter/filter-name

filter-classorg.apache.shiro.web.servlet.ShiroFilter/filter-class

/filter

filter-mapping

filter-nameshiroFilter/filter-name

url-pattern/*/url-pattern

/filter-mapping

2.shiro.ini配置

[main]

[filters]

#自定义realm

shiroAuthorizingRealm = com.frame.security.ShiroAuthorizingRealm

securityManager.realm = $shiroAuthorizingRealm

# 声明一个自定义的用户校验拦截器

customFormAuthenticationFilter = com.frame.security.CustomFormAuthenticationFilter

# 声明一个自定义的用户角色权限拦截器

customPermissionsAuthorizationFilter = com.frame.security.CustomPermissionsAuthorizationFilter

#cache

shiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManager

shiroCacheManager.cacheManagerConfigFile = classpath:ehcache.xml

securityManager.cacheManager = $shiroCacheManager

#session

sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager

sessionManager.sessionDAO = $sessionDAO

securityManager.sessionManager = $sessionManager

securityManager.sessionManager.globalSessionTimeout = 1800000

securityManager = org.apache.shiro.web.mgt.DefaultWebSecurityManager

[urls]

/admin/user/login = anon

/admin/user/logout = anon

/admin/user/registered = anon

/admin/** = customFormAuthenticationFilter,customPermissionsAuthorizationFilter

从shiro.ini配置中可以看出,需要三个文件,分别为ShiroAuthorizingRealm.java(realm文件),CustomFormAuthenticationFilter.java(自定义用户登陆验证文件),CustomPermissionsAuthorizationFilter(自定义用户角色权限文件);

在urls配置中可以看出不需要拦截的url后面加上anon便可,但有先后顺序。

缓存是使用ehcache

3.ehcache.xml配置

cache name="defaultCache" maxElementsInMemory="500"

maxElementsOnDisk="10000000" eternal="true" overflowToDisk="true"

diskSpoolBufferSizeMB="50" /

cache name="shiro-activeSessionCache" maxElementsInMemory="500"

maxElementsOnDisk="10000000" eternal="true" overflowToDisk="true"

diskSpoolBufferSizeMB="50" /

cache name="jdbcRealm.authorizationCache" maxElementsInMemory="500"

maxElementsOnDisk="10000000" eternal="true" overflowToDisk="true"

diskSpoolBufferSizeMB="50" /

cache name="authorization" maxElementsInMemory="500"

timeToLiveSeconds="3600" eternal="false" overflowToDisk="false" /

4.ShiroAuthorizingRealm.java

public class ShiroAuthorizingRealm extends AuthorizingRealm {

private AuthorityService authorityService = FrameContext.getBean(AuthorityService.class);

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

System.out.println("=======doGetAuthenticationInfo=======");

UsernamePasswordToken userToken = (UsernamePasswordToken) token;

String username = userToken.getUsername();

String password = String.valueOf(userToken.getPassword());

User user = User.dao.findFirst("select * from m_user where account = ?", username);

if (user != null) {//下面可以做一些登陆的操作,密码错误,用户状态等等

if(MD5Encoder.validPassword(password, user.getPassword())==false){

throw new UnknownAccountException();

}

SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());

return info;

} else {

return null;

}

}

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

System.out.println("=======doGetAuthorizationInfo=======");

User user = (User) principals.getPrimaryPrincipal();

if(user!=null){//从数据库中读取用户的角色权限,

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

ListString perms = authorityService.getUrlByUser(user);

if(perms!=nullperms.size()0){//调用addStringPermissions方法把用户的权限信息添加到info中,可以addRoles方法把用户的角色添加到了info中

info.addStringPermissions(perms);

}

return info;

}

return null;

}

}

5.CustomFormAuthenticationFilter.java

public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {

private final static Logger log = Logger.getLogger(CustomFormAuthenticationFilter.class);

private static final String contentType = "application/json; charset=UTF-8";

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

HttpServletRequest httpRequest = WebUtils.toHttp(request);

HttpServletResponse httpResponse = WebUtils.toHttp(response);

if (isLoginRequest(request, response)) {

if (isLoginSubmission(request, response)) {

if (log.isTraceEnabled()) {

log.trace("Login submission detected. Attempting to execute login.");

}

return executeLogin(request, response);

} else {

if (log.isTraceEnabled()) {

log.trace("Login page view.");

}

return true;

}

} else {

ResultObject result = new ResultObject(false, "401", "没有授权,请先登录", null);

renderJson(httpResponse, result);

return false;

}

}

private void renderJson(HttpServletResponse response, Object object) {

String jsonText = JsonKit.toJson(object);

PrintWriter writer = null;

try {

response.setHeader("Pragma", "no-cache"); // HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache

response.setHeader("Cache-Control", "no-cache");

response.setDateHeader("Expires", 0);

response.setContentType(contentType);

writer = response.getWriter();

writer.write(jsonText);

writer.flush();

} catch (IOException e) {

throw new RenderException(e);

}

finally {

if (writer != null) {

writer.close();

}

}

}

}

6.CustomPermissionsAuthorizationFilter.java

public class CustomPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {

private static final String contentType = "application/json; charset=UTF-8";

private AuthorityService authorityService = McmsContext.getBean(AuthorityService.class);

@Override

public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {

if(getMappedValue(request)!=null){

return super.isAccessAllowed(request, response, getMappedValue(request));

}

return false;

}

@Override

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {

// TODO Auto-generated method stub

HttpServletRequest httpRequest = WebUtils.toHttp(request);

HttpServletResponse httpResponse = WebUtils.toHttp(response);

String path = httpRequest.getServletPath();

Subject subject = getSubject(request, response);

if (subject.isPermitted(path)) {

return true;

} else {

ResultObject result = new ResultObject(false, "401", "抱歉,您没有该权限!", null);

renderJson(httpResponse, result);

return false;

}

}

/**

* 得到mappedValue,相当于perms[user:add]中的“user:add”

* @param path

* @return

*/

public String[] getMappedValue(ServletRequest request) {

HttpServletRequest req = (HttpServletRequest) request;

String path = req.getServletPath();

String code = getCodesByPath(path);

if(null == code) {

return null;

}

return new String[]{code};

}

/**

* 根据访问路径获取权限代码

* @param path

* @return

*/

public String getCodesByPath(String path) {

User user = (User) SecurityUtils.getSubject().getPrincipal();

String pers = authorityService.getUrlByUserPath(path,user);

return Optional.ofNullable(pers).orElse(null);

}

private void renderJson(HttpServletResponse response, Object object) {

String jsonText = JsonKit.toJson(object);

PrintWriter writer = null;

try {

response.setHeader("Pragma", "no-cache"); // HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache

response.setHeader("Cache-Control", "no-cache");

response.setDateHeader("Expires", 0);

response.setContentType(contentType);

writer = response.getWriter();

writer.write(jsonText);

writer.flush();

} catch (IOException e) {

throw new RenderException(e);

}

finally {

if (writer != null) {

writer.close();

}

}

}

}

7.用户登陆入口

public void login() {

String account = getPara("account");

String password = getPara("password");

Subject subject = SecurityUtils.getSubject();

UsernamePasswordToken tokens = new UsernamePasswordToken(account, password);

tokens.setRememberMe(false);

try {

subject.login(tokens);

User user = (User) subject.getPrincipal();

loginSuccess(user);

UserVo userVo = convertToUserVO(user);

renderSucessResult(userVo);

} catch (UnknownAccountException ue) {

tokens.clear();

renderFailedResult("登录失败!无效的账号或密码!");

} catch (IncorrectCredentialsException ie) {

tokens.clear();

renderFailedResult("用户已注销!");

} catch(LockedAccountException le){

tokens.clear();

renderFailedResult("账号被锁定!");

} catch (RuntimeException re) {

re.printStackTrace();

tokens.clear();

renderFailedResult("登录失败!");

}

}

数据库可以自己去设计,这里就不提供了。

参照上面的去整合框架,便可以使用了,这样搭建适合多种框架的整合。

如何使用Shiro实现不同用户登录成功后跳转到不同主页

登陆成功后获取 Subject 对象.

然后通过 Subject 对象来判断当前用户的角色/权限, 之后执行不同的跳转(直接在LoginAction中做).

我的登陆部分代码:

Java代码

UsernamePasswordToken token = new UsernamePasswordToken(name, password);

try {

SecurityUtils.getSubject().login(token);

Subject subject = SecurityUtils.getSubject();

// 这里可以调用subject 做判断

System.out.println("--------------------------------------------------------------");

Boolean isadmin = subject.hasRole("admin");

log.info("是否为管理员:"+isadmin);

System.out.println("--------------------------------------------------------------");

String userId = (String)subject.getPrincipal();

User user = userService.getById(userId);

ShiroUser shiroUser = shiroUserService.getByDyId(userId);

if(shiroUser == null){

this.addActionError(getText("login.failure"));

return ERROR;

}else{

int used = shiroUser.getUsed();

if(used == 1){

this.addActionError(getText("login.noused"));

return ERROR;

}

}

Session session = subject.getSession(true);

session.setAttribute(LoginAction.USER_KEY, user);

session.setAttribute(LoginAction.SHIRO_USER_KEY, shiroUser);

log.info("set workflow define to session");

session.setAttribute("ptDefine", WorkflowContext.getPtDefine());

} catch (AuthenticationException e) {

log.info(e.getMessage());

this.addActionError(getText("login.failure"));

}

if (this.hasErrors()) {

log.info("login erro ...");

return ERROR;

}

java里shiro的用法

好在配置简单,以前做一个权限模块要写好多代码。现在spring security好像是集成了shiro的功能,实现了代码量更少,高速开发的目的。

利用第三方包(例OpenSSL,Shiro)实现DES算法,用java语言…急求!在线等

不需要第三方包,java自带就有。我给你个例子。

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.security.Security;

import javax.crypto.BadPaddingException;

import javax.crypto.Cipher;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.KeyGenerator;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.SecretKey;

public class EncrypDES {

//KeyGenerator 提供对称密钥生成器的功能,支持各种算法

private KeyGenerator keygen;

//SecretKey 负责保存对称密钥

private SecretKey deskey;

//Cipher负责完成加密或解密工作

private Cipher c;

//该字节数组负责保存加密的结果

private byte[] cipherByte;

public EncrypDES() throws NoSuchAlgorithmException, NoSuchPaddingException{

Security.addProvider(new com.sun.crypto.provider.SunJCE());

//实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)

keygen = KeyGenerator.getInstance("DES");

//生成密钥

deskey = keygen.generateKey();

//生成Cipher对象,指定其支持的DES算法

c = Cipher.getInstance("DES");

}

/**

 * 对字符串加密

 * 

 * @param str

 * @return

 * @throws InvalidKeyException

 * @throws IllegalBlockSizeException

 * @throws BadPaddingException

 */

public byte[] Encrytor(String str) throws InvalidKeyException,

IllegalBlockSizeException, BadPaddingException {

// 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式

c.init(Cipher.ENCRYPT_MODE, deskey);

byte[] src = str.getBytes();

// 加密,结果保存进cipherByte

cipherByte = c.doFinal(src);

return cipherByte;

}

/**

 * 对字符串解密

 * 

 * @param buff

 * @return

 * @throws InvalidKeyException

 * @throws IllegalBlockSizeException

 * @throws BadPaddingException

 */

public byte[] Decryptor(byte[] buff) throws InvalidKeyException,

IllegalBlockSizeException, BadPaddingException {

// 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式

c.init(Cipher.DECRYPT_MODE, deskey);

cipherByte = c.doFinal(buff);

return cipherByte;

}

/**

 * @param args

 * @throws NoSuchPaddingException 

 * @throws NoSuchAlgorithmException 

 * @throws BadPaddingException 

 * @throws IllegalBlockSizeException 

 * @throws InvalidKeyException 

 */

public static void main(String[] args) throws Exception {

EncrypDES de1 = new EncrypDES();

String msg ="郭XX-搞笑相声全集";

byte[] encontent = de1.Encrytor(msg);

byte[] decontent = de1.Decryptor(encontent);

System.out.println("明文是:" + msg);

System.out.println("加密后:" + new String(encontent));

System.out.println("解密后:" + new String(decontent));

}

}

如何关闭Shiro会话问题,怎么解决

看看 开涛shiro第二十章

Subject工厂

Java代码

public class StatelessDefaultSubjectFactory extends DefaultWebSubjectFactory {

public Subject createSubject(SubjectContext context) {

//不创建session

context.setSessionCreationEnabled(false);

return super.createSubject(context);

}

}

!-- 会话管理器 --

bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager"

property name="sessionValidationSchedulerEnabled" value="false"/

/bean

session如何在java代码中判断是否过期

系统框架使用的springmvc 。。。。

在controller层上做了拦截器,添加了自定义标签,使用了该标签则需要校验session是否过期,过期则跳转至登录页面,但是系统用到了shiro,请问在java代码中如何判断seesion已经过期

Subject currentUser = SecurityUtils.getSubject();

Session session = currentUser.getSession();

//过期,则跳转登录页面重新登录

if () { //就是这里不知道如何写!!!!!!!!!!!!!!!!!!!!!

dosomething;。。。。

shiro配置如下:

!-- 会话DAO --

bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"

property name="activeSessionsCacheName" value="shiro-activeSessionCache"/

property name="sessionIdGenerator" ref="sessionIdGenerator"/

/bean

!-- 会话验证调度器 --

bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler"

property name="sessionValidationInterval" value="1800000"/

property name="sessionManager" ref="sessionManager"/

/bean

!-- 会话管理器 --

bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"

property name="globalSessionTimeout" value="1800000"/!-- 回话有效时间30分钟 --

property name="deleteInvalidSessions" value="true"/

property name="sessionValidationSchedulerEnabled" value="true"/

property name="sessionValidationScheduler" ref="sessionValidationScheduler"/

property name="sessionDAO" ref="sessionDAO"/

property name="sessionIdCookieEnabled" value="true"/

property name="sessionIdCookie" ref="sessionIdCookie"/

/bean

希望能帮到楼主, 谢谢


当前名称:shiro的java代码,shirodkar
转载来源:http://ybzwz.com/article/dsehoie.html