SpringBoot详解(六) 从入门到入土 (shiro 邮件)

八、SpringSecurity(安全)

安全框架,简单说是对访问权限进行控制,应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。

用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。

用户认证一般要求用户提供用户名和密码,系统通过校验用户名和密码来完成认证过程。

用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。

一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

config文件下创建XxxConfig 继承 WebSecurityConfigurerAdapter 类 在方法上加上@EnableWebSecurity

开启Security

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {
       //首页所有人可以访问,功能页只要对应有权限的人才可以访问

        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

        http.formLogin().loginPage("/toLogin");

        //注销功能
        http.csrf().disable();
        http.logout().logoutSuccessUrl("/");
        //记住我
        http.rememberMe();

    }
    //认证

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("xm").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
    }
}

九、shiro

SpringBoot详解(六) 从入门到入土 (shiro 邮件)_第1张图片

SpringBoot详解(六) 从入门到入土 (shiro 邮件)_第2张图片

1. 导入依赖

		<dependency>
            <groupId>org.apache.shirogroupId>
            <artifactId>shiro-coreartifactId>
            <version>1.5.2version>
        dependency>
        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>jcl-over-slf4jartifactId>
            <version>1.7.21version>
        dependency>
        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-log4j12artifactId>
            <version>1.7.21version>
        dependency>
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>1.2.17version>
        dependency>

2.log4j.properties

# Global logging configuration 开发时候建议使用 debug
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

3.shiro.ini

需要下载ini插件

在resource下创建shiro.ini

[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz

# -----------------------------------------------------------------------------
# Roles with assigned permissions
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5

4.快速开始

Quickstart.java

5.Subject对象

//得到当前对象的用户对象 Subject
Subject currentUser = SecurityUtils.getSubject();
 //通过当前用户获得shiro Session
        Session session = currentUser.getSession();
//判断当前的用户是否被认证
        if (!currentUser.isAuthenticated()) {
        
        }
//获得当前用户的认证
currentUser.getPrincipal()
//是否拥有这个角色
currentUser.hasRole("schwartz")
//获得当前用户的权限
currentUser.isPermitted("lightsaber:wield")
//all done - log out!注销
currentUser.logout();

6.SpringBoot整合shiro

Subject 用户

SecurityManager 管理所有用户

Realm 连接数据

整合

1.导入依赖

<dependency>
            <groupId>org.apache.shirogroupId>
            <artifactId>shiro-springartifactId>
            <version>1.5.1version>
        dependency>

2.shiro的配置

创建config.UserRealm 和 config.ShiroConfig

UserRealm

自定义的realm extends AuthorizingRealm

public class UserRealm extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权");
        return null;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了认证");
        return null;
    }
}

ShiroConfig

@Configuration
public class ShiroConfig {
    //ShiroFilterFactoryBean 3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        return bean;
    }

    //DefaultWebSecurityManager 2
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //创建realm对象,需要自定义 1
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

3.登录拦截

添加Shiro的内置过滤器

 @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);

        //添加shiro的内置过滤器
        /*
            anon : 无需认证就可以访问
            authc: 必须认证了才能访问
            user: 必须拥有记住我功能才能用
            perms: 拥有对某个资源的权限才能访问
            role: 拥有某个角色权限才能访问
        * */
        Map<String, String> filterMap = new LinkedHashMap<>();

        //filterMap.put("/user/add", "authc");
        //filterMap.put("/user/update", "authc");
        filterMap.put("/user/*", "authc");
        bean.setFilterChainDefinitionMap(filterMap);
        //设置登录的请求
        bean.setLoginUrl("/toLogin");

        return bean;
    }

4.用户认证(数据库中)

UserRealmAuthenticationInfo 方法中

//认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了认证");
        //用户 密码 数据库取 token 令牌
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        User user = userService.queryUserByName(userToken.getUsername());
        if (user == null){
            return null;
        }
        //可以加密 :MD5   MD5盐值加密
            //密码认证 不需要处理 shiro 处理 加密了
            return new SimpleAuthenticationInfo("", user.getPwd(), "");
    }

连接数据库 整合MyBatis

从前端接收用户名,密码并判断

@RequestMapping("/login")
    public String login(String username,String password,Model model){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装当前用户的信息
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            //执行登录的方法 没有异常则OK
            subject.login(token);
            return "index";
        }catch (UnknownAccountException e){
             model.addAttribute("msg","用户名错误");
             return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }

    }

5.请求授权

ShiroConfiggetShiroFilterFactoryBean方法

 //授权 必须是user才有add权限
        filterMap.put("/user/add", "perms[user:add]");

SpringBoot详解(六) 从入门到入土 (shiro 邮件)_第3张图片

没有权限会报401错误

 //未授权页面
        bean.setUnauthorizedUrl("/noauth");

十、任务

异步任务

普通的Thread .sleep(3000); 浏览器会转3s 没有页面信息,非常影响用户体验。

而加入注解就可以解决没有页面信息的问题

  • 在service方法上加入**@Async**注解
  • 在main主方法上加上**@EnableAsync**注解

这样 浏览器就会即时返回页面信息 3s后后台处理信息

邮件任务

发送邮件

导入依赖

		<dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-mailartifactId>
        dependency>
@Autowired
JavaMailSenderImpl mailSender;

@Test
    void contextLoads() {
        //简单的邮件
        SimpleMailMessage mailMessage = new SimpleMailMessage();//2.需要这个参数就new这个参数

        mailMessage.setSubject("你好!");//主题
        mailMessage.setText("xxxxx");//正文

        mailMessage.setTo("[email protected]");//发给谁
        mailMessage.setFrom("[email protected]");//谁发的

        mailSender.send(mailMessage);// 1.方法
    }
@Test
    void contextLoad2() throws MessagingException {
        MimeMessage mimeMessage = mailSender.createMimeMessage();//2.new 这个参数

        //正文
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
        helper.setSubject("XMXMXMXMXM");//主题
        helper.setText("

谢谢谢谢!

"
,true);//正文 //附件 helper.addAttachment("1.png", new File("C:\\Users\\Administrator\\Desktop\\新建文件夹\\images\\1.png")); helper.setTo("[email protected]");//发给谁 helper.setFrom("[email protected]");//谁发 mailSender.send(mimeMessage);//1.方法 }

定时任务

在特定的时间执行任务

  • 在主方法main 上加上注解@EnableScheduling
  • service类的需要加上定时任务的方法上加上@Scheduled(cron = “0 * * * * 0-7”)

cron = “0 * * * * 0-7” 秒 分 时 日 月 每周(0 7都表示星期天) 每60秒执行一次方法

下一篇学习
SpringBoot详解(六) 从入门到入土 (shiro 邮件)

你可能感兴趣的:(springboot,shiro,spring,java)