① 如何正确的使用shiro
从来没接触过shiro java安全框架,突然有一天需要要用用户登陆验证和用户角色权限的任务,而且是针对shiro 进行整合,开始收到任务,心都有点凉凉的。经过一轮的搜索,感觉没多大的收获。很多用户的角色都是写在xml配置文件中。觉得太不人性化了,想换个用户角色还得改xml?我觉得这么强大的框架应该不可能这么狗血的存在。然后认真的看文档,发现真的是可以直接读取数据库的。我把我搭建的流程发布在此。有问题的可以交流交流。我写的也并不是正确的,只能参考参考。1.web.xml的配置<listener><listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class></listener><filter><filter-name>shiroFilter</filter-name><filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class></filter><filter-mapping><filter-name>shiroFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>2.shiro.ini配置[main][filters]#自定义realmshiroAuthorizingRealm = com.frame.security.ShiroAuthorizingRealmsecurityManager.realm = $shiroAuthorizingRealm# 声明一个自定义的用户校验拦截器 = com.frame.security.# 声明一个自定义的用户角色权限拦截器 = com.frame.security.#cacheshiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManagershiroCacheManager.cacheManagerConfigFile = classpath:ehcache.xmlsecurityManager.cacheManager = $shiroCacheManager#sessionsessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAOsessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManagersessionManager.sessionDAO = $sessionDAOsecurityManager.sessionManager = $sessionManagersecurityManager.sessionManager.globalSessionTimeout = 1800000securityManager = org.apache.shiro.web.mgt.DefaultWebSecurityManager[urls]/admin/user/login = anon/admin/user/logout = anon/admin/user/registered = anon/admin/** = ,从shiro.ini配置中可以看出,需要三个文件,分别为ShiroAuthorizingRealm.java(realm文件),.java(自定义用户登陆验证文件),(自定义用户角色权限文件);在urls配置中可以看出不需要拦截的url后面加上anon便可,但有先后顺序。缓存是使用ehcache3.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.javapublic class ShiroAuthorizingRealm extends AuthorizingRealm {private AuthorityService authorityService = FrameContext.getBean(AuthorityService.class);@Overrideprotected 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..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;}}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {System.out.println("=======doGetAuthorizationInfo=======");User user = (User) principals.getPrimaryPrincipal();if(user!=null){//从数据库中读取用户的角色权限,SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();List<String> perms = authorityService.getUrlByUser(user);if(perms!=null&&perms.size()>0){//调用addStringPermissions方法把用户的权限信息添加到info中,可以addRoles方法把用户的角色添加到了info中info.addStringPermissions(perms);}return info;}return null;}}5..javapublic class extends FormAuthenticationFilter {private final static Logger log = Logger.getLogger(.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 {Result<Object> result = new Result<Object>(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-cacheresponse.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..javapublic class extends {private static final String contentType = "application/json; charset=UTF-8";private AuthorityService authorityService = McmsContext.getBean(AuthorityService.class);@Overridepublic boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {if(getMappedValue(request)!=null){return super.isAccessAllowed(request, response, getMappedValue(request));}return false;}@Overrideprotected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {// TODO Auto-generated method stubHttpServletRequest 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 {Result<Object> result = new Result<Object>(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-cacheresponse.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 多入口登录 如何配置xml文件
/itjob/login.action = anon //允许匿名访问路径 设置为anon就可/itjob2/login2.action = anon //允许匿名访问路径 设置为anon就可
③ shiro框架 配置文件log4j.properties shiro在哪
log4j.properties和shiro没关系哦。
推荐一套完整的Shiro Demo,免费的。
Shiro介绍文档:http://www.sojson.com/shiroDemo已经部署到线上,地址是http://shiro.itboy.net,
管理员帐号:admin,密码专:sojson.com 如果密码错误,请用sojson。PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,属每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快。
④ ssm框架访问控制应该怎么做
这个就在在人员表了添加一个身份的字段 user_rank ,用这个来控制。用户登录到时候就会用登录信息,把这个 user_rank 字段带出来,在页面或者链接时候加上判断,哈这是简单的,看下官方的。
shiro安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证、授权、加密和会话管理等功能 。
shiro能做什么?
认证:验证用户的身份
授权:对用户执行访问控制:判断用户是否被允许做某事
会话管理:在任何环境下使用 Session API,即使没有 Web 或EJB 容器。
加密:以更简洁易用的方式使用加密功能,保护或隐藏数据防止被偷窥
Realms:聚集一个或多个用户安全数据的数据源
单点登录(SSO)功能。
为没有关联到登录的用户启用 "Remember Me“ 服务
Shiro 的四大核心部分
Authentication(身份验证):简称为“登录”,即证明用户是谁。
Authorization(授权):访问控制的过程,即决定是否有权限去访问受保护的资源。
Session Management(会话管理):管理用户特定的会话,即使在非 Web 或 EJB 应用程序。
Cryptography(加密):通过使用加密算法保持数据安全
shiro的三个核心组件:
Subject:正与系统进行交互的人,或某一个第三方服务。所有 Subject 实例都被绑定到(且这是必须的)一个SecurityManager 上。
SecurityManager:Shiro 架构的心脏,用来协调内部各安全组件,管理内部组件实例,并通过它来提供安全管理的各种服务。当 Shiro 与一个 Subject 进行交互时,实质上是幕后的 SecurityManager 处理所有繁重的 Subject 安全操作。
Realms:本质上是一个特定安全的 DAO。当配置 Shiro 时,必须指定至少一个 Realm 用来进行身份验证和/或授权。Shiro 提供了多种可用的 Realms 来获取安全相关的数据。如关系数据库(JDBC),INI 及属性文件等。可以定义自己 Realm 实现来代表自定义的数据源。
shiro整合SSM框架:
1.加入 jar 包:以下jar包自行网络下载
准备好了,接下来要写Realm方法了,新建shiro包,在包下新建MyRealm.java文件继承AuthorizingRealm
package shiro;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.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.crypto.hash.Md5Hash;import org.apache.shiro.crypto.hash.SimpleHash;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import org.springframework.beans.factory.annotation.Autowired;import bean.user;import .user;public class MyRealm extends AuthorizingRealm {@Autowired private user user;String pass; /*** 授权:**/@Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();Object principal = principalCollection.getPrimaryPrincipal();//获取登录的用户名if("admin".equals(principal)){ //两个if根据判断赋予登录用户权限info.addRole("admin");} if("user".equals(principal)){info.addRole("list");}info.addRole("user");return info;} /** 用户验证**/@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//1. token 中获取登录的 username! 注意不需要获取password.Object principal = token.getPrincipal();//2. 利用 username 查询数据库得到用户的信息.user user=user.findbyname((String) principal); if(user!=null){pass=user.getPass();}String credentials = pass; //3.设置盐值 ,(加密的调料,让加密出来的东西更具安全性,一般是通过数据库查询出来的。 简单的说,就是把密码根据特定的东西而进行动态加密,如果别人不知道你的盐值,就解不出你的密码)String source = "abcdefg";ByteSource credentialsSalt = new Md5Hash(source);//当前 Realm 的nameString realmName = getName(); //返回值实例化SimpleAuthenticationInfo info =new SimpleAuthenticationInfo(principal, credentials,credentialsSalt, realmName);return info;} //init-method 配置.public void setCredentialMatcher(){HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();credentialsMatcher.setHashAlgorithmName("MD5");//MD5算法加密credentialsMatcher.setHashIterations(1024);//1024次循环加密setCredentialsMatcher(credentialsMatcher);}//用来测试的算出密码password盐值加密后的结果,下面方法用于新增用户添加到数据库操作的,我这里就直接用main获得,直接数据库添加了,省时间public static void main(String[] args) {String saltSource = "abcdef";String hashAlgorithmName = "MD5";String credentials = "passwor";Object salt = new Md5Hash(saltSource); int hashIterations = 1024;Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);System.out.println(result);}}
好了,接下来我们写一个简单的action来通过shiro登录验证。
//登录认证 @RequestMapping("/shiro-login") public String login(@RequestParam("username") String username, @RequestParam("password") String password){ Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { //执行认证操作. subject.login(token); }catch (AuthenticationException ae) { System.out.println("登陆失败: " + ae.getMessage()); return "/index"; } return "/shiro-success"; }
//温馨提示:记得在注册中密码存入数据库前也记得加密哦,提供一个utils方法//进行shiro加密,返回加密后的结果public static String md5(String pass){String saltSource = "blog"; String hashAlgorithmName = "MD5";Object salt = new Md5Hash(saltSource);int hashIterations = 1024; Object result = new SimpleHash(hashAlgorithmName, pass, salt, hashIterations);String password = result.toString();return password;}
好了,shiro登录验证到这里完了
⑤ shiro 为什么用ini作为配置文件
开发者是这么设计的,坦白说,确实不太方便,不过与框架整合时,基本上都不再创建ini配置文件,如与spring整合,直接放到spring中配置bean
⑥ shiro记住我cookie无法添加 按照网上的说法 把配置文件中所有的配置都写了 javabea
ie11下查看cookie:1:IE11=》F12打开开发人员工具2:开发人员工具=》网络F5启用网络流量捕获3:IE11=》输入和访问相关网址4:开发人员工具=》网络=》详细信息=》Cookie如果你只在java后台写的cookie,前端浏览器当然看不到
⑦ shiro技术四大组件和运行原理是什么
subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。 securityManager:安全管理器,主体进行认证和授权都是通过securityManager进行。 authenticator:认证器,主体进行认证最终通过authenticator进行的。 authorizer:授权器,主体进行授权最终通过authorizer进行的。 认证执行流程1、通过ini配置文件创建securityManager2、调用subject.login方法主体提交认证,提交的token3、securityManager进行认证,securityManager最终由MolarRealmAuthenticator进行认证。4、MolarRealmAuthenticator调用IniRealm(给realm传入token) 去ini配置文件中查询用户信息5、IniRealm根据输入的token(UsernamePasswordToken)从 shiro.ini查询用户信息,根据账号查询用户信息(账号和密码) 如果查询到用户信息,就给MolarRealmAuthenticator返回用户信息(账号和密码) 如果查询不到,就给MolarRealmAuthenticator返回null6、MolarRealmAuthenticator接收IniRealm返回Authentication认证信息 如果返回的认证信息是null,MolarRealmAuthenticator抛出异常
⑧ shiro 如何配置到tomcat应用上
1 、 首先 创建一个项目名(mail)的文件夹, 在项目文件夹下创建一个存放JS脚本的文件夹,创建一个存放images(图片)的文件夹,创建一个存放CSS样式的文件夹等。 2、 然后在项目文件夹下创建一个WEB-INF的目录文件,JAVA类、jar包、WEB应用的配置文件都存在这个目录下。WEB-INF目录下存放了一些文件,有classes目录(编译好的类库)、lib目录, 每一个WEB应用程序的访问都需要一个配置文件,基于WEB.xml文件,所以在WEB-INF 文件目录下应该创建一个WEB.xml文件。 3、 在所创建的项目mail文件夹下创建一个HTML文件,名为index.html。在HTML文件中编辑一些内容。 4、 在tomcat目录文件夹下的conf文件的Catalina\Localhost文件夹下新建一个名为mail.xml的项目文件,在这个文件中编辑代码,写一个Context的配置的路径 如: <?xml version='1.0' encoding='utf-8'?> <Context docBase=”C:\mail”/> 5、 最后重新启动Comcat就可以了。