美文网首页
(四)整合servlet

(四)整合servlet

作者: guideEmotion | 来源:发表于2019-06-22 22:08 被阅读0次

    一 修改web.xml

    修改web.xml,在里面加了个过滤器.将shiro的初始化,交给过滤器器来工作

    <web-app>
        <listener>
            <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
        </listener>
        <context-param>
            <param-name>shiroEnvironmentClass</param-name>
            <param-value>org.apache.shiro.web.env.IniWebEnvironment</param-value><!-- 默认先从/WEB-INF/shiro.ini,如果没有找classpath:shiro.ini -->
        </context-param>
        <context-param>
            <param-name>shiroConfigLocations</param-name>
            <param-value>classpath:shiro.ini</param-value>
        </context-param>
        <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>
    </web-app>
    
    

    二 Realm

    这里是一个最简单的实现realm

    
    package com.how2java;
    
    import java.util.Set;
    
    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.UsernamePasswordToken;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    
    public class DatabaseRealm extends AuthorizingRealm {
    
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            //能进入到这里,表示账号已经通过验证了
            String userName =(String) principalCollection.getPrimaryPrincipal();
            //通过DAO获取角色和权限
            Set<String> permissions = new DAO().listPermissions(userName);
            Set<String> roles = new DAO().listRoles(userName);
            
            //授权对象
            SimpleAuthorizationInfo s = new SimpleAuthorizationInfo();
            //把通过DAO获取到的角色和权限放进去
            s.setStringPermissions(permissions);
            s.setRoles(roles);
            return s;
        }
    
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            //获取账号密码
            UsernamePasswordToken t = (UsernamePasswordToken) token;
            String userName= token.getPrincipal().toString();
            String password= new String( t.getPassword());
            //获取数据库中的密码
            String passwordInDB = new DAO().getPassword(userName);
    
            //如果为空就是账号不存在,如果不相同就是密码错误,但是都抛出AuthenticationException,而不是抛出具体错误原因,免得给破解者提供帮助信息
            if(null==passwordInDB || !passwordInDB.equals(password)) 
                throw new AuthenticationException();
            
            //认证信息里存放账号密码, getName() 是当前Realm的继承方法,通常返回当前类名 :databaseRealm
            SimpleAuthenticationInfo a = new SimpleAuthenticationInfo(userName,password,getName());
            return a;
        }
    
    }
    
    

    三 登陆Servlet

    package com.how2java;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    
    @WebServlet(name = "loginServlet", urlPatterns = "/login")  
    public class LoginServlet extends HttpServlet {  
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
          throws ServletException, IOException {  
            String name = req.getParameter("name");  
            String password = req.getParameter("password");  
            Subject subject = SecurityUtils.getSubject();  
            UsernamePasswordToken token = new UsernamePasswordToken(name, password);  
            try {  
                subject.login(token);
                Session session=subject.getSession();
                session.setAttribute("subject", subject);
                
                resp.sendRedirect("");
            } catch (AuthenticationException e) {  
                req.setAttribute("error", "验证失败");  
                req.getRequestDispatcher("login.jsp").forward(req, resp); 
            }  
        }  
    }  
    
    

    四 配置文件

    [main] 
    #使用数据库进行验证和授权
    databaseRealm=com.how2java.DatabaseRealm
    securityManager.realms=$databaseRealm
     
    #当访问需要验证的页面,但是又没有验证的情况下,跳转到login.jsp
    authc.loginUrl=/login.jsp
    #当访问需要角色的页面,但是又不拥有这个角色的情况下,跳转到noroles.jsp
    roles.unauthorizedUrl=/noRoles.jsp
    #当访问需要权限的页面,但是又不拥有这个权限的情况下,跳转到noperms.jsp
    perms.unauthorizedUrl=/noPerms.jsp
     
    #users,roles和perms都通过前面知识点的数据库配置了
    [users] 
     
    #urls用来指定哪些资源需要什么对应的授权才能使用
    [urls] 
    #doLogout地址就会进行退出行为
    /doLogout=logout
    #login.jsp,noroles.jsp,noperms.jsp 可以匿名访问
    /login.jsp=anon
    /noroles.jsp=anon
    /noperms.jsp=anon
     
    #查询所有产品,需要登录后才可以查看
    /listProduct.jsp=authc 
    #删除商品不仅需要登录,而且要拥有 productManager 权限才可以操作
    /deleteProduct.jsp=authc,roles[productManager] 
    #删除订单,不仅需要登录,而且要拥有 deleteOrder 权限才可以操作
    /deleteOrder.jsp=authc,perms["deleteOrder"]  
    

    参考

    1. http://how2j.cn/k/shiro/shiro-web/1722.html#nowhere

    相关文章

      网友评论

          本文标题:(四)整合servlet

          本文链接:https://www.haomeiwen.com/subject/hncbqctx.html