[main]
  # 身份认证,若没有登录则跳转到 /login
  authc.loginUrl=/login
  # 角色认证,若无此角色的用户将跳转到 /unauthorized.jsp
  roles.unauthorizedUrl=/unauthorized.jsp
  # 权限认证,若无权限则跳转到 /unauthorized.jsp
  perms.unauthorizedUrl=/unauthorized.jsp
  [users]
  lee1=123, admin
  lee2=456, teacher
  lee3=789
  [roles]
  admin=user:*, student:*
  teacher=student:*
  # 该 urls 里的所有 url 都将被右边的过滤器拦截
  # ? 匹配单个字符,如:/admin? -> /admin1、/admin2
  # * 匹配零个或多个字符,如:/admin* -> /admin、/admin1、/admin123
  # ** 匹配多个路径,如:/admin/** -> /admin/、/admin/1、/admin/1/2
  [urls]
  # 需要 anon 权限才能访问,anon 表示不需要权限,游客
  /login=anon
  # 首先需要登录,判断有 admin 权限的用户才能访问
  /admin=roles[admin]
  # 访问 /student 需要角色需要有 teacher
  /student=roles[teacher]
  # 访问 /teacher 需要有 user:create
  /teacher=perms[user:create]
  LoginServlet.java
  import org.apache.shiro.SecurityUtils;
  import org.apache.shiro.authc.AuthenticationException;
  import org.apache.shiro.authc.UsernamePasswordToken;
  import org.apache.shiro.subject.Subject;
  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 java.io.IOException;
  @WebServlet(urlPatterns = "/login") // 需 web 3.0
  public class LoginServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  System.out.println("login doGet");
  req.getRequestDispatcher("login.jsp").forward(req, resp);
  }
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  System.out.println("login doPost");
  String username = req.getParameter("username");
  String password = req.getParameter("password");
  Subject subject = SecurityUtils.getSubject();
  UsernamePasswordToken token = new UsernamePasswordToken(username, password);
  try {
  subject.login(token);
  resp.sendRedirect("success.jsp");
  } catch (AuthenticationException e) {
  e.printStackTrace();
  req.setAttribute("errorInfo", "用户名或密码错误");
  req.getRequestDispatcher("login.jsp").forward(req, resp);
  }
  }
  }
  Default Filters
  Default Filters 是 Shiro 提供给我们的 Web 过滤器,他们将拦截各种请求,并判断是否有权限访问。
  身份验证 authc
  org.apache.shiro.web.filter.authc.FormAuthenticationFilter
  基于表单的拦截器;
  如“/**=authc”,如果没有登录会跳到相应的登录页面登录;
  主要属性:usernameParam:表单提交的用户名参数名( username);
  passwordParam:表单提交的密码参数名(password);
  rememberMeParam:表单提交的密码参数名(rememberMe);
  loginUrl:登录页面地址(/login.jsp);
  successUrl:登录成功后的默认重定向地址;
  failureKeyAttribute:登录失败后错误信息存储key(shiroLoginFailure);
  authcBasic
  org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
  Basic HTTP身份验证拦截器,主要属性:
  applicationName:弹出登录框显示的信息(application);
  logout
  org.apache.shiro.web.filter.authc.LogoutFilter
  退出拦截器,主要属性:
  redirectUrl:退出成功后重定向的地址(/);
  示例“/logout=logout”
  user
  org.apache.shiro.web.filter.authc.UserFilter
  用户拦截器,用户已经身份验证/记住我登录的都可;
  示例“/**=user”
  anon
  org.apache.shiro.web.filter.authc.AnonymousFilter
  匿名拦截器,即不需要登录即可访问;
  一般用于静态资源过滤;
  示例“/static/**=anon”
  授权相关 roles
  org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
  角色授权拦截器,验证用户是否拥有所有角色;
  主要属性: loginUrl:登录页面地址(/login.jsp);
  unauthorizedUrl:未授权后重定向的地址;
  示例“/admin/**=roles[admin]”
  perms
  org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
  权限授权拦截器,验证用户是否拥有所有权限;
  属性和roles一样;
  示例“/user/**=perms[“user:create”]”
  port
  org.apache.shiro.web.filter.authz.PortFilter
  端口拦截器,主要属性:port(80):可以通过的端口;
  示例“/test= port[80]”,如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样
  rest
  org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
  rest风格拦截器,自动根据请求方法构建权限字符串
  (GET=read, POST=create,PUT=update,DELETE=delete,
  HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create)
  构建权限字符串;
  示例“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll);
  ssl
  org.apache.shiro.web.filter.authz.SslFilter
  SSL拦截器,只有请求协议是https才能通过;
  否则自动跳转会https端口(443);
  其他和port拦截器一样;
  其他 noSessionCreation
  org.apache.shiro.web.filter.session.NoSessionCreationFilter
  不创建会话拦截器,调用 subject.getSession(false)不会有什么问题,
  但是如果 subject.getSession(true)将抛出 DisabledSessionException异常;
  自定义 Realm
  在认证、授权内部实现机制中都有提到,终处理都将交给Real进行处理。因为在Shiro中,终是通过Realm来获取应用程序中的用户、角色及权限信息的。通常情况下,在Realm中会直接从我们的数据源中获取Shiro需要的验证信息。可以说,Realm是专用于安全框架的DAO。
  如何编写自定义 Realm
  CustomizeRealm.java
  import com.lee.shiro.dao.UserDao;
  import com.lee.shiro.dao.impl.UserDaoImpl;
  import com.lee.shiro.entity.User;
  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 java.util.Set;
  public class CustomizeRealm extends AuthorizingRealm {
  private UserDao userDao = new UserDaoImpl();
  /**
  * 为当前用户授权
  * 先执行 doGetAuthenticationInfo(token)
  * 然后执行此方法
  *
  * @param principalCollection
  * @return
  */
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
  String username = (String) principalCollection.getPrimaryPrincipal();
  SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();
  Set<String> rolesSet = userDao.getRolesByUsername(username);
  Set<String> permissionSet = userDao.getPermissionsByUsername(username);
  authInfo.setRoles(rolesSet);
  authInfo.setStringPermissions(permissionSet);
  return authInfo;
  }
  /**
  * 验证当前登录的用户
  *
  * @param token
  * @return
  * @throws AuthenticationException
  */
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  String username = (String) token.getPrincipal();
  User user = userDao.getByUsername(username);
  AuthenticationInfo authInfo = null;
  if (user != null) {
  authInfo = new SimpleAuthenticationInfo(
  user.getUsername(), user.getPassword(), "userRealm");
  }
  return authInfo;
  }
  }