美文网首页
一、工作流 Activiti7-13.SpringSecurit

一、工作流 Activiti7-13.SpringSecurit

作者: 那钱有着落吗 | 来源:发表于2021-04-07 09:11 被阅读0次
image.png image.png

1.实战

首先我们需要新增这么个依赖,当然如果已经引用了Activiti7的话,是默认带有的

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

然后启动项目,在控制台是有一个密码的:


image.png

把这个复制好,然后再打开项目地址,就会有提示要输入账号密码,我们输入:
user 刚赋值的密码,就可以登录访问接口了。

我们再模拟一下登录:
我们实现UserDetailsService类,然后重写该方法,写死正确的密码111,然后重启,发现用户名什么都行,密码一定要是111才可以验证成功,至于为什么这里可以写死密码,可以自定debug看源码就知道了(大概就是Security可以自己拿到输入框的密码,然后与该方法传入密码对比)

@Configuration
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        String password = passwordEncoder().encode("111");

        return new User(userName,password,
                AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ACTIVITI_USER"));
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

下面我们实现从数据库读取用户,然后可以成功登陆:


@Data
@Component
public class UserInfo implements UserDetails {


    private Long id;
    private String name;
    private String username;
    private String password;
    private String address;
    private String roles;

    private String getAddress(){
        return address;
    }

    /**
     * Returns the authorities granted to the user. Cannot return <code>null</code>.
     *
     * @return the authorities, sorted by natural key (never <code>null</code>)
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Arrays.stream(roles.split(",")).map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList());
    }

    /**
     * Returns the password used to authenticate the user.
     *
     * @return the password
     */
    @Override
    public String getPassword() {
        return password;
    }

    /**
     * Returns the username used to authenticate the user. Cannot return
     * <code>null</code>.
     *
     * @return the username (never <code>null</code>)
     */
    @Override
    public String getUsername() {
        return username;
    }

    /**
     * Indicates whether the user's account has expired. An expired account cannot be
     * authenticated.
     *
     * @return <code>true</code> if the user's account is valid (ie non-expired),
     * <code>false</code> if no longer valid (ie expired)
     */
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    /**
     * Indicates whether the user is locked or unlocked. A locked user cannot be
     * authenticated.
     *
     * @return <code>true</code> if the user is not locked, <code>false</code> otherwise
     */
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    /**
     * Indicates whether the user's credentials (password) has expired. Expired
     * credentials prevent authentication.
     *
     * @return <code>true</code> if the user's credentials are valid (ie non-expired),
     * <code>false</code> if no longer valid (ie expired)
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    /**
     * Indicates whether the user is enabled or disabled. A disabled user cannot be
     * authenticated.
     *
     * @return <code>true</code> if the user is enabled, <code>false</code> otherwise
     */
    @Override
    public boolean isEnabled() {
        return true;
    }
}

上面对应的是数据库中的user表,这个user表在本系列课程前面导入过一次,不了解的可以翻翻。

创建一个根据用户名查询用户的方法:

@Service
public class UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    //根据用户名查询用户
    public UserInfo findByUserName(String userName){
        return jdbcTemplate.queryForObject("select * from user where username='"+userName+"'",
                BeanPropertyRowMapper.newInstance(UserInfo.class));
    }
}
 @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        UserInfo userInfo = userService.findByUserName(userName);
        if(userInfo==null){
            throw  new UsernameNotFoundException("数据库中没有此用户");
        }
        return userInfo;
    }

这样做就是从数据库中把用户给查询出来然后验证登录了。

2.登录接口配置

首先我们需要编写登录配置信息

@Configuration
public class ActivitySecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception{
        httpSecurity.formLogin()
                .loginPage("/login")
                .successHandler(loginSuccessHandler)
                .and()
                .authorizeRequests()
                .anyRequest().permitAll().and().logout().permitAll()
                .and().csrf().disable().headers().frameOptions().disable();
    }
}

在配置中,我们制定loginPage,这个可以指定页面或者方法,上面我们指定了方法,意思就是访问login这个接口就会走Security框架的登录验证。
successHandler 我们填写的是注入的loginSuccessHandler类,其他的都是开放登录的配置,例如anyRequest().permitAll(),.logout().permitAll()都是允许登录登出的接口访问,csrf().disable().这个是允许ajax访问,frameOptions允许前端的frame框架登录。

重写登录成功之后的方法处理

@Component("loginSuccessHandler")
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    //表单
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.getWriter().write("登录成功LoginSuccessHandler");
    }

    //ajax
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {

    }
}

这个时候我们在进行ajax发送请求认证,成功。


image.png

除了登录成功的处理方法,我们还需要处理登录失败的方法:

@Component("loginFailureHandler")
public class LoginFailureHandler implements AuthenticationFailureHandler {

    /**
     * Called when an authentication attempt fails.
     *
     * @param request   the request during which the authentication attempt occurred.
     * @param response  the response.
     * @param exception the exception which was thrown to reject the authentication
     */
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("登录失败,原因是:"+exception.getMessage());
    }
}
image.png image.png

登录失败配置好之后,登录接口就可以在失败的时候给与良好的提示信息了。

接下来,我们还需要配置一个未登录用户需要跳转的接口:

@Slf4j
@RestController
public class ActivitySecurityController {

    @RequestMapping(path = "login")
    @ResponseStatus(code=HttpStatus.UNAUTHORIZED)
    public String requiredAuth(HttpServletRequest request, HttpServletResponse response) {
        return "需要登录,请使用login.html或发起POST登录请求!";
    }

}
 @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception{
        httpSecurity.formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .successHandler(loginSuccessHandler)
                .failureHandler(loginFailureHandler)
                .and()
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated().and().logout().permitAll()
                .and().csrf().disable().headers().frameOptions().disable();
    }

这样的话,如果没有登录就会跳转到统一的页面进行提示了。

在实际开发中可以通过判断请求的来源,如果是表单的话就可以提示跳转到登录页面,如果是ajax就提示信息即可。

相关文章

  • 一、工作流 Activiti7-13.SpringSecurit

    1.实战 首先我们需要新增这么个依赖,当然如果已经引用了Activiti7的话,是默认带有的 然后启动项目,在控制...

  • 五分钟了解Activiti工作流

    什么是工作流 说到工作流,一图胜万言。 工作流 Georgakopoulos给出的工作流定义是:工作流是将一组任务...

  • Java 实现简单工作流

    工作流主要运用到反射机制 创建一张工作流表如:主键 | 工作流Code | 工作流内容 其中工作流,内容为Json...

  • Activiti工作流

    1.工作流简介 1.1工作流与工作流引擎 工作流(workflow)就是工作流程的计算模型,即将工作流程中的工作如...

  • Git工作流指南

    今天看了一下翻译的git工作流指南,简单总结一下。 Git工作流指南Git工作流指南:集中式工作流Git工作流指南...

  • springboot2整合Activiti7

    【1】初识activiti 1.1. 工作流与工作流引擎 工作流工作流(workflow)就是工作流程的计算模型,...

  • Activiti教程(一)初识

    【1】初识activiti 1.1. 工作流与工作流引擎工作流工作流(workflow)就是工作流程的计算模型,将...

  • Common Workflow Language [五]

    二十一 嵌套工作流 问题:如何将多个工作流连接在一起? 目标:了解如何从多个CWL工作流构造嵌套工作流。 工作流是...

  • Java工作流详解(附6大工作流框架对比)

    目录 1.什么是工作流 2.工作流应用场景 3.工作流实现方式 4.有哪些工作流框架? 什么是工作流工作流(Wor...

  • 驰骋工作流引擎开发平台属性功能的隐藏显示介绍

    关键字: 工作流程管理系统 工作流引擎 asp.net工作流引擎 java工作流引擎. 表单引擎 工作流功能说明...

网友评论

      本文标题:一、工作流 Activiti7-13.SpringSecurit

      本文链接:https://www.haomeiwen.com/subject/hlbzcltx.html