1.首先要搭建SSM框架
2.引入ssm相关依赖
<!--shiro相关依赖-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>
基本ssm框架整合其他技术都是在spring中引入一个bean实现整合(小白自己的理解)
3.在web.xml中配置shiro的
<!--shiro的filter-->
<!--shiro过滤器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由Servlet容器管理控制filter的生命周期 -->
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
shiro也是通过过滤器进行拦截的,filter进行拦截过后找到spring中所配置的过滤链,shiro中提供了很多filter
4.配置spring-shiro
<!-- Shiro 的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!--配置登录界面-->
<property name="loginUrl" value="/login.action" />
<!--配置成功认证后跳转的url只是附属配置,实际上跳转的是上一次请求的url-->
<property name="successUrl" value="/index.jsp"/>
<!--认证未成功跳转的界面-->
<property name="unauthorizedUrl" value="/index.jsp" />
<!--引入自己定义的重写了表单过滤器的过滤器-->
<property name="filters">
<map>
<entry key="authc" value-ref="formAuthenticationFilter" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
/login.action=authc
</value>
</property>
</bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm" />
</bean>
<!-- 自定义 realm -->
<bean id="userRealm" class="realm.CustomRealm"/>
<!--重写的表单过滤器-->
<bean id="formAuthenticationFilter" class="filter.MyFormAuthenticationFilter">
<property name="loginUrl" value="/login.action"/>
</bean>
</beans>
其中有几点需要注意:
1. 配置的LoginURL就是登录界面, 而不是表单的提交界面
2.successURL只是 一种附属配置,当认证成功后session中保存的是上一次 请求的URL, 所以认证成功后并不会跳转到successurl,而是跳转到上一次 请求的URL也就是返回Loginurl登陆界面。一正常情况下成功返回login,在controller中处理失败跳转的页面。当然也可以通过重载 formauthenticafilter的方法来实现successURL的跳转
3.shiro中的过滤器
5.重写authorizingrealm
public class CustomRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
public String getName() {
return "CustomRealm";
}
/*实现授权的方法*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String userCode=(String)principals.getPrimaryPrincipal();
List<String> role=userService.role(userCode);
SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addRoles(role);
return simpleAuthorizationInfo;
}
/*实现认证的方法*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
/*从token中取出用户凭证*/
String userCode=(String)token.getPrincipal();
User user=userService.login(userCode);
System.out.println(user);
if(user!=null){
String password=user.getPassword();
System.out.println(password);
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password, this.getName());
return simpleAuthenticationInfo;
}
return null;
}
}
6.controller
@RequestMapping(value = "/check.action")
public String check(@RequestParam("username")String username,@RequestParam("password")String password) {
if(username!=null && password!=null){
Subject subject= SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
try{
subject.login(token);
return "success";
}catch (Exception e){
e.printStackTrace();
}
}else{
System.out.println("请输入用户名或密码");
}
return "login";
}
shiro认证的总结: 用户登录是在一个表单中进行的,所以需要通过shiro的一个表单过滤器(formauthenticationfilter)进行实现的,其原理如下:
用户没有认证时,请求Loginurl进行认证,输入信息后点击提交数据到LoginURL,然后formauthenticationfilter过滤器进行拦截取出其中的username和password(表单中的用户名和密码智能是username和password), 如果想改动的话可以在spring-shiro文件中进行配置formauthenticationfilter重新对其命名。然后formauthenticationfilter会调用realm传入一个token(token里面封装这用户信息),realm认证时根据username在数据库只能怪查询用户信息,然后返回一个SimplAuthenticationInfo(进行校验)。
有些controller代码只处理 错误信息返回错误界面,controller中
Subject subject= SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(username,password); subject.login(token);
其实在formauthenticationfilter内部 就已经调用了的。但是我把loginurl配置成登录界面formauthenticationfilter根本就不进行拦截,所以根本不能进入realm,所以 只能在controller中自己 动手获取username和password然后login()。如果有大牛知道哪里错的话,希望能够帮忙指点哪里不对。