shiro使用与我遇到的问题

来源:互联网 发布:身份证拍照扫描软件 编辑:程序博客网 时间:2024/06/06 02:37

我遇到的问题:使用shiro进行登录的时候可以选择两种方案,一种是自动生成token,一种手动生成
第一种:name=”username”,name=”password”只能写这两个(目测是这样)
表单:

<TR>    <TD>用户名:</TD>    <TD colSpan="2"><input type="text" id="usercode"        name="username" style="WIDTH: 130px" /></TD></TR><TR>    <TD>密 码:</TD>    <TD><input type="password" id="pwd" name="password" style="WIDTH: 130px" />    </TD></TR>

控制器:

// 登陆提交地址,和applicationContext-shiro.xml中配置的loginurl一致@RequestMapping("login")public String login(HttpServletRequest request) throws Exception {    // 如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名    String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");    // 根据shiro返回的异常类路径判断,抛出指定异常信息    if (exceptionClassName != null) {        if (UnknownAccountException.class.getName().equals(exceptionClassName)) {            // 最终会抛给异常处理器            throw new CustomException("账号不存在");        } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {            throw new CustomException("用户名/密码错误");        } else if ("randomCodeError".equals(exceptionClassName)) {            throw new CustomException("验证码错误 ");        } else {            throw new Exception();// 最终在异常处理器生成未知错误        }    }    // 此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径    // 登陆失败还到login页面    return "login";}

认证:

// 用于认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {    // token是用户输入的    // 第一步从token中取出身份信息    String userCode = (String) token.getPrincipal();    // 第二步:根据用户输入的userCode从数据库查询    // ....    // 如果查询不到返回null    // 数据库中用户账号是zhangsansan    if (!userCode.equals("zhangsan")) {        return null;    }    // 模拟从数据库查询到密码    String password = "123";    // 如果查询到返回认证信息AuthenticationInfo    SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password,this.getName());    return simpleAuthenticationInfo;}

第二种倒是没限制

控制器:

@RequestMapping("/login")public String login(@RequestParam("username") String username, @RequestParam("password") String password) {    Subject currentUser = SecurityUtils.getSubject();    if (!currentUser.isAuthenticated()) {        // 把用户名密码封装为UsernamePasswordToken对象        UsernamePasswordToken token = new UsernamePasswordToken(username.trim(), password.trim());        // RememberMe 记住我属性        token.setRememberMe(true);        try {            // 执行登录            currentUser.login(token);        }        // 所有认证时异常的父类.        catch (AuthenticationException ae) {            System.out.println("登录失败:" + ae.getMessage());        }    }    return "redirect:/list.jsp";}

认证:

@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {    // 1. 把 AuthenticationToken 转换为 UsernamePasswordToken    UsernamePasswordToken upToken = (UsernamePasswordToken) token;    // 2. 从 UsernamePasswordToken 中来获取 username    String username = upToken.getUsername();    // 3. 调用数据库的方法, 从数据库中查询 username 对应的用户记录    System.out.println("从数据库中获取 username: " + username + " 所对应的用户信息.");    // 4. 若用户不存在, 则可以抛出 UnknownAccountException 异常    if ("unknow".equals(username)) {        throw new UnknownAccountException("用户名不存在");    }    // 5. 根据用户信息的情况, 决定是否需要抛出其他的 AuthenticationException 异常.    if ("monster".equals(username)) {        throw new LockedAccountException("用户被锁定");    }    // 6. 根据用户的情况, 来构建 AuthenticationInfo 对象并返回. 通常使用的实现类为:    // SimpleAuthenticationInfo    // 以下信息是从数据库中获取的.    // 1). principal: 认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象.    Object principal = username;    // 2). credentials: 密码.    Object credentials = null;// "8e56a40e92622217019f774aa9d9afdc";    credentials = new SimpleHash("MD5", "123456", username, 1);    // 3). realmName: 当前 realm 对象的 name. 调用父类的 getName() 方法即可    String realmName = getName();    // 4). 盐值    ByteSource credentialsSalt = ByteSource.Util.bytes(username);    // SimpleAuthenticationInfo info = new    // SimpleAuthenticationInfo(principal, credentials, realmName);    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt,            realmName);    return info;}

shiro的jar包

与其它java开源框架类似,将shiro的jar包加入项目就可以使用shiro提供的功能了。shiro-core是核心包必须选用,还提供了与web整合的shiro-web、与spring整合的shiro-spring、与任务调度quartz整合的shiro-quartz等,下边是shiro各jar包的maven坐标。<dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-core</artifactId>    <version>1.2.3</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-web</artifactId>    <version>1.2.3</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-spring</artifactId>    <version>1.2.3</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-ehcache</artifactId>    <version>1.2.3</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-quartz</artifactId>    <version>1.2.3</version></dependency>也可以通过引入shiro-all包括shiro所有的包:<dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-all</artifactId>    <version>1.2.3</version></dependency>

shiro过滤总结

过滤器简称   对应的java类anon        org.apache.shiro.web.filter.authc.AnonymousFilterauthc       org.apache.shiro.web.filter.authc.FormAuthenticationFilterauthcBasic  org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilterperms       org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilterport        org.apache.shiro.web.filter.authz.PortFilterrest        org.apache.shiro.web.filter.authz.HttpMethodPermissionFilterroles       org.apache.shiro.web.filter.authz.RolesAuthorizationFilterssl         org.apache.shiro.web.filter.authz.SslFilteruser        org.apache.shiro.web.filter.authc.UserFilterlogout      org.apache.shiro.web.filter.authc.LogoutFilteranon:例子/admins/**=anon 没有参数,表示可以匿名使用。authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,没有参数 roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为httpsuser:例如/admins/user/**=user没有参数表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查注:anon,authcBasic,auchc,user是认证过滤器,perms,roles,ssl,rest,port是授权过滤器

在springmvc.xml中配置shiro注解支持,可在controller方法中使用shiro注解配置权限:

<!-- 开启aop,对类代理 --><aop:config proxy-target-class="true"></aop:config><!-- 开启shiro注解支持 --><bean    class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">    <property name="securityManager" ref="securityManager" /></bean>

或者在spring中配置:

<bean    class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"    depends-on="lifecycleBeanPostProcessor" /><bean    class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">    <property name="securityManager" ref="securityManager" /></bean>