springboot学习整理3:整合shiro部分

首先搭建shiro的登录环境
1建立对应的文件login.jsp,login.js
注意点:静态文件必须放在新建的webapp目录的WEB-INF目录下,我之前在这边栽了很多次,当你的静态文件没有放到webapp目录下,而是放到类似于resources(根目录的)目录下,springboot是找不到的,即使你在静态资源映射配置中设了也不行。
2.设置视图解析器
springboot中的视图解析器是在自定义的webMvc配置类中重写addViewResolver方法。
这里我是用了jsp支持的jstl类,设置路径返回的url的前缀跟后缀。(springboot中的提供了在properties中设置前后缀的属性)
3.设置静态资源的映射
同理,springboot静态资源的映射也是在自定义的webMvc配置类中重写addResources***方法,通过设置registry的addResources跟addResourcesLocation方法.addResources()中添加所要映射的url,意味着匹配的url都会转换为location后面的url。

设置完启动springboot,打开login页面,控制台可能会报jstl的config类NotFoundException,我们需要在pom中添加jstl的依赖:

	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>jstl</artifactId>
		<version>1.2</version>
	</dependency>

重新打开login页面。如果这次提示的是下载login这个文件,说明现在没有支持tomcat的返回,
需要在pom中添加浏览器对tomcat的支持依赖:

	<dependency>
		<groupId>org.apache.tomcat.embed</groupId>
		<artifactId>tomcat-embed-jasper</artifactId>
		<version>9.0.14</version>
	</dependency>

自此,我们重新启动springboot,应该能访问的到login页面。
控制台如果报no mapper ** found ,检查下自己的视图解析器跟静态资源映射有没有写对。
配置类的Configuration注解有没有加,主程序的EnableWebMvc注解有没有。
控制台如果没有报错,输出iframework 初始化完成,那么就检查下你的静态文件有没有放到webapp目录下。

配置shiro
shiro留给我们做的工作其实很简单,shiro已经帮我们在org.apache.shiro下完成了认证,授权的前后过程,我们只要为我们的项目去编写对应的认证,授权条件跟流程。
1.编写自定义的Realm
shiro提供了AuthorizingRealm这个父类,我们只需要编写个AuthorizingRealm的子类去实现我们业务认证授权的代码:

public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserReposity userReposity;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();
        User user = userReposity.findOneByUsername(username);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for(Role role : user.getRoleSet()){
            simpleAuthorizationInfo.addRole(role.getRoleName());
        }
        simpleAuthorizationInfo.addStringPermission(user.getPermission());
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        if(authenticationToken.getPrincipal() == null){
            return null;
        }

        String username = (String) authenticationToken.getPrincipal();
        User user = userReposity.findOneByUsername(username);
        if(user == null){
            return null;
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,user.getUserPassword(),getName());
        return simpleAuthenticationInfo;
    }
}

认证方法doGetAuthorizationInfo:
用户登录的时候我们需要认证当前登录的用户,authenticationToken中保存了用户的信息,getPrincipal()方法可以获取到用户的username,
然后通过我们业务的dao层去获取当前用户名在数据库信息,之后交给simpleAuthenticationInfo 对象去进行校验。如果用户名账号密码匹配,则返回一个正常的simpleAuthenticationInfo 对象,里面会有用户认证成功的信息。如果密码不匹配,则抛出NoAcountExcetion或者密码不正确的异常。
授权方法doGetAuthorizationInfo:
用户认证完成之后会进行授权流程,授权流程是在登陆成功之后才会走。授权会给将用户的角色信息,权限信息都返回给simpleAuthorizationInfo对象。我们可以在此利用simpleAuthorizationInfo对象给用户弹出对应于其角色跟权限的菜单。

进行授权完成之后,我们可以在一些加了权限注解的方法上进行角色,权限的控制

    @RequestMapping("create")
    @RequiresPermissions({"save"})
    @RequiresRoles({"admin"})
    public Map<String,Object> save(){
        concurrentMap.put("data","success");
        return concurrentMap;
    }

@RequiresPermissions是对所有未拥有其参数的权限的用户进行拦截,@RequiresRoles则是对非admin用户进行拦截。这个方法就是角色为admin且拥有save权限的用户开放。
自定义的realm完成之后,就需要写一个shiro配置类去配置我们完成的realm

编写shiro配置类

@Configuration
public class ShiroFilter {}

将MyShiroRealm放入到容器中

 @Bean
    public MyShiroRealm myShiroRealm(){
        return new MyShiroRealm();
    }

将安全管理器SecurityManager放入到容器中,并且为其配上realm

 @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

将ShiroFilterFactoryBean 放入到容器中,并且为ShiroFilterFactoryBean 设置安全管理器securityManager。shiroFilterFactoryBean需要注意的 重点:

  1. setLoginUrl设置起始登录的页面login,该设置成功以后,所有未经过认证的用户对服务器进行访问都只会弹出login这个地址。
  2. setSuccessUrl设置认证成功之后弹出的地址index.
  3. setFilterChainDefinitionMaps设置地址过滤的细节
    map.put("/",“authc”);意味着所有的url请求都要经过认证;
    map.put("/**",“user”);所有url请求在登录之后不做检查;
    map.put("/",“anno”);所有url请求支持匿名访问,就是不设检查
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> map = new HashMap<>();
        map.put("/**","user");
        map.put("/**","authc");
        // 设置login页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 设置index主页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

当发现请求的jsp文件无法找到对应的js文件时,检查这里是不是没有对js等资源文件做匿名访问的支持。

这里AuthorizationAttributeSourceAdvisor 的作用暂时不明。

  @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

这里贴下我controller的代码

@Controller
public class LoginController {
    private final ConcurrentMap<String,Object> concurrentMap = new ConcurrentHashMap<>();

    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(){
        return new "login";
    }

    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(User user){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUserName(),user.getUserPassword());
        subject.login(usernamePasswordToken);
        return "redirect:/index";
    }
    @RequestMapping("/error")
    public String error(){
        return "error";
    }

    @RequestMapping("/index")
    public String index(){
        return "index";
    }

    @RequestMapping("create")
    @RequiresPermissions({"save"})
    @RequiresRoles({"admin"})
    public Map<String,Object> save(){
        concurrentMap.put("data","success");
        return concurrentMap;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值