您的位置:首页 > 编程语言 > Java开发

ssm框架下的网上书城项目的开发-springboot使用shiro(认证和权限)

2019-04-11 18:14 399 查看

   shiro的官方文档下第一句就介绍了shiro的作用:

    Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. 

  简单来说,shiro有四大功能:authentication(认证),authorization(授权),cryptography(加密),session mangement(session 管理)。

  本篇文章我们在springboot下来使用shiro完成前面两个功能的简单应用。(后面两个还在学习中)

第一步 首先我们要做的当然是导入依赖:

[code]<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>

   第二步:我们开始建shiro配置类也就是下面的config.MyShiroRelam和ShiroConfig

现在我们开始写这两个配置类。

首先写ShiroConfig,它拥有三个方法,我们可以通过下面的图片看到,首先要建的是getRealm()方法,然后getDefaWebSecurityManager()使用了realm方法,getShiroFilterFactoryBean()使用了getDefaWebSecurityManager()方法。这些基本都是固定的套路,我们先把他们写好。

下面我们写MyshiroRelam.java,因为之前的getRealm方法需要MyshiroRelam类,所以没写此类前面肯定会一直报错,我们也可以将这个类先完成。首先它要继承AuthorizingRealm这个方法,并实现doGetAuthorizationInfo和doGetAuthenticationInfo两个方法的重写。根据这两个方法的意思我们也大概能理解这两个方法的作用了,前者是处理权限问题,后面是处理认证的问题。  再写之前我们还要完成一些准备工作,那就是写一些前台网页来进行验证。由下图我们就能知道,都是一些非常简单的功能,这里要说一下,由于之前的项目没有考虑shiro的功能,尤其是权限字符段,进行整合有些难度,因此本文只是介绍一些基础的用法,具体的整合要在之后进行。

 

 

 在完成这几步后,我们就可以开始shiro的整理了

ShiroConfig.java主要写的是我们的映射规则,其中我们调用的setLoginUrl方法可以帮助我们设定用户没有认证时的跳转页面,这里我们设定的登录页面,否则他会默认选择跳转login.jsp;setUnauthorizedUrl方法则是可以帮助我们设定用户没有权限的跳转画面。

另外我们还要注意filterMap.put("/shiro/*","authc");这行代码一定要在后面项目才能正常运行。d

[code]@Configuration
public class ShiroConfig {

@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
/*anon 无需认证    user 必须remember功能
* authc 必须认证   perms 资源权限 role 角色权限
* */
Map<String,String> filterMap =new LinkedHashMap<String, String>();
filterMap.put("/shiro/shiroToLogin","anon");//当我们进入登录页面,无需认证
filterMap.put("/shiro/shiroLogin","anon");
filterMap.put("/shiro/shiroAdd","perms[user:add]");//我们给shiroAdd设置了一定的权限
filterMap.put("/shiro/*","authc");// /shiro/*的url请求我们都需要认证
shiroFilterFactoryBean.setLoginUrl("/shiro/shiroLogin");//设置认证页面
shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");   //设置无权限认证页面
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}

@Bean(name = "defaultManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("realm") MyShiroRelam realm){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return  securityManager;

}

@Bean("realm")
public MyShiroRelam getRealm(){
return  new MyShiroRelam();
}

}

我们在这里写MyShiroRelam。

1.权限验证,我们需要在这里设置一个字符串(可以从数据库查找)和在shiroConfig里的字符串对比,确定该用户或资源是否有此权限。此权限的口令也可以由字符串的数组组成。

2.登录验证:在这里我们向数据库根据姓名查询用户,如果没有,我们返回null,抛出用户不存在的异常,

                    如果存在,我们得到用户的信息,也包括用户的密码,我们只需把密码传入SimpleAuthenticationInfo()方法即可,如果密码失败,它也会自动帮我们抛出异常。

[code]@Configuration
public class MyShiroRelam extends AuthorizingRealm {

@Autowired
LoginService loginService;

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行授权逻辑");
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addStringPermission("user:add");//验证授权逻辑
return info;
}

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行认证逻辑");

UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken;
User user= loginService.findByName(token.getUsername());//使用findByName方法检验数据库里是否由该用户,如果有,返回该用户的信息(返回该用户的密码,方便我们下一步认证)
if(user==null){
return null;
}//我们验证用户是否存在,如果失败,它会抛出异常UnknownAccountException
return new SimpleAuthenticationInfo("",user.getPassword(),"");
//验证密码是否正确,如果失败,它会抛出异常IncorrectCredentialsException
}
}

最后是我们的controller层

ShiroTestController.java.

我们可以从代码中看到,我们捕获异常,然后在前台显示各自的提示信息并跳转到登录页面,如果没有异常,那我们最终运行成功,可以进入main页面。

[code]@Controller
public class ShiroTestController {

@RequestMapping("/shiro/shiroLogin")
public String shiroLogin()    { return "shiro/shiroLogin"; }
@RequestMapping("/shiro/shiroMain")
public String shiroMain()     { return "shiro/shiroMain"; }
@RequestMapping("/shiro/shiroAdd")
public String shiroAdd()      { return "shiro/shiroAdd"; }
@RequestMapping("/shiro/shiroUpdate")
public String shiroUpdate()   { return "shiro/shiroUpdate"; }
@RequestMapping("/shiro/shiroFailed")
public String shiroFailed()   { return "shiro/shiroFailed"; }
@RequestMapping("/noAuth")
public String shiroNoAuth()   { return "shiro/shiroFailed"; }

@RequestMapping("/shiro/shiroToLogin")
public String shiroToLogin(String username, String password, Model model) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
} catch (UnknownAccountException e) {
model.addAttribute("msg", "没有该用户");

20000
return "/shiro/shiroLogin";
} catch (IncorrectCredentialsException e) {
model.addAttribute("msg", "密码错误");
return "/shiro/shiroLogin";
}
return "/shiro/shiroMain";
}
}

shiro还有两大功能我们并没有涉及,只能等以后在学习了。本文并没有涉及到更深层面,只是对shiro框架进行了简单的应用。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐