2020.09-Study_update.1

week 8.31-9.6

-Study-update
-Monelement-ui 前端表单校验
--
-Study-update
-Thu动态代理复习
-Fri工厂模式练习 security登陆表单
-Sat方法安全权限
-Sun从数据库验证账户密码

8.31 Monday

登陆表单前端页面
Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可

<template>
    <div>
        <el-form :rules="rules" v-model="loginForm" class="loginContainer">
            <h1 class="loginTitle">登陆系统</h1>
            <el-form-item prop="username">
                用户名:
                <el-input type="text" v-model="loginForm.username" auto-complete="off" placeholder="请输入用户名"></el-input>
            </el-form-item>
            <el-form-item prop="password">
                用户名:
                <el-input type="text" v-model="loginForm.password" auto-complete="off" placeholder="请输入密码"></el-input>
            </el-form-item>
            <el-checkbox v-model="checked"></el-checkbox>
            <el-button type="primary" style="width: 100%">登陆</el-button>

        </el-form>
    </div>
</template>

<script>
    export default {
        name: "Login",

        data() {
            return {
                loginForm: {username: '', password: ''},
                rules: {
                    username: [
                        {required: true, message: '请输入用户名', trigger: 'blur'}
                    ],
                    password: [
                        {required: true, message: '请输入密码', trigger: 'blur'}
                    ]
                },
                checked: true
            }
        }
    }
</script>

<style>
    .loginContainer{
        border: 1px solid silver;
        border-radius: 15px;
        background-clip: padding-box;
        margin: 180px auto;
        width: 350px;
        padding: 35px 35px 15px 35px;
        background: white;
        box-shadow: 0 0 25px silver;
    }
    .loginTitle{
        color: gray;
        margin: 0px auto 0px auto;
        text-align: center;
    }
</style>

9.3 Thursday

书本工厂接口

package com.maaoooo.dynamicProxy;

/**
 * @author lzr
 * @date 2020/9/3 10:53:12
 * @description 出售书的接口
 */
public interface SellBooks {
    void sellBook(double price);
}
书本工厂

```java
package com.maaoooo.dynamicProxy;

/**
 * @author lzr
 * @date 2020/9/3 10:53:57
 * @description 书本工厂类
 */
public class StroyBookFactory implements SellBooks {
    public void sellBook(double price) {
        System.out.println("购买了故事书,价格为:"+price);
    }
}

香水工厂接口
```java
package com.maaoooo.dynamicProxy;

/**
 * @author lzr
 * @date 2020/9/3 10:50:59
 * @description 出售香水的接口
 */
public interface SellPerfume {
    void sellPerfume(double price);
}

香水工厂

package com.maaoooo.dynamicProxy;

/**
 * @author lzr
 * @date 2020/9/3 10:51:39
 * @description 香奈儿香水工厂类
 */
public class ChanelFactrory implements SellPerfume {
    public void sellPerfume(double price) {
        System.out.println("购买香水,价格为:"+price);
    }
}

代理工厂

package com.maaoooo.dynamicProxy;

import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @author lzr
 * @date 2020/9/3 10:55:13
 * @description  代理工厂
 */
public class SellProxyFactory implements InvocationHandler {
    private Object realObject;

    public SellProxyFactory(Object realObject) {
        this.realObject = realObject;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("收取手续费10%");
        Object obj = method.invoke(realObject, args);
        double price = Double.parseDouble(args[0].toString());
        System.out.println("最终价格为:"+price*1.1);
        return obj;
    }
}

购买者测试

package com.maaoooo.dynamicProxy;

import java.lang.reflect.Proxy;

/**
 * @author lzr
 * @date 2020/9/3 10:54:38
 * @description 测试购买
 */
public class Buyer {
    public static void main(String[] args) {
        ChanelFactrory chanelFactrory = new ChanelFactrory();
        SellProxyFactory perfumeSeller = new SellProxyFactory(chanelFactrory);
        SellPerfume perfume = (SellPerfume) Proxy.newProxyInstance(chanelFactrory.getClass().getClassLoader(), chanelFactrory.getClass().getInterfaces(), perfumeSeller);
        perfume.sellPerfume(2000);


        StroyBookFactory stroyBookFactory = new StroyBookFactory();
        SellProxyFactory bookSeller = new SellProxyFactory(stroyBookFactory);
        SellBooks sellBook = (SellBooks) Proxy.newProxyInstance(stroyBookFactory.getClass().getClassLoader(), stroyBookFactory.getClass().getInterfaces(), bookSeller);
        sellBook.sellBook(1000);
    }
}

运行结果
在这里插入图片描述

主要
代理工厂实现InvocationHandler 接口。实现invoke()方法
invoke() 方法有3个参数:

  • Object proxy:代理对象
  • Method method:真正执行的方法
  • Object[] agrs:调用第二个参数 method 时传入的参数列表值

生成时用到Proxy类

 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);

实例化代理对象时,需要传入3个参数:

  • ClassLoader loader:加载动态代理类的类加载器
  • Class<?>[] interfaces:代理类实现的接口,可以传入多个接口
  • InvocationHandler h:指定代理类的「调用处理程序」,即调用接口中的方法时,会找到该代理工厂h,执行invoke()方法

9.4 Friday

用工厂模式提供加减乘除的运算类

package factory;

/**
 * @author lzr
 * @date 2020/9/4 09:43:55
 * @description 算法接口
 */
public interface Algorithm {
    public double getResult(double a,double b);
}

package factory;

/**
 * @author lzr
 * @date 2020/9/4 09:44:42
 * @description 加法实现
 */
public class Add implements Algorithm {

    public double getResult(double a, double b) {
        return a+b;
    }
}

package factory;

/**
 * @author lzr
 * @date 2020/9/4 09:45:27
 * @description 减法实现
 */
public class Sub implements Algorithm {
    public double getResult(double a, double b) {
        return a-b;
    }
}

package factory;

/**
 * @author lzr
 * @date 2020/9/4 09:45:47
 * @description 乘法实现
 */
public class Mul implements Algorithm {
    public double getResult(double a, double b) {
        return a*b;
    }
}

package factory;

/**
 * @author lzr
 * @date 2020/9/4 09:46:17
 * @description 除法实现
 */
public class Division implements Algorithm {
    public double getResult(double a, double b) {
        if(a==0){
            throw new RuntimeException("除数不能为0");
        }
        return a/b;
    }
}

package factory;

/**
 * @author lzr
 * @date 2020/9/4 09:47:25
 * @description 算法工厂
 */
public class ComputeFactory {
    public static Algorithm getAlgorithm(String symbol) {
        if ("+".equals(symbol)) {
            return new Add();
        } else if ("-".equals(symbol)) {
            return new Sub();
        } else if ("*".equals(symbol)) {
            return new Mul();
        } else if ("/".equals(symbol)) {
            return new Division();
        }
        throw new RuntimeException("符号错误");
    }
}

package factory;

/**
 * @author lzr
 * @date 2020/9/4 09:51:49
 * @description 测试
 */
public class FactoryTest {
    public static void main(String[] args) {
        Algorithm addAlgorithm = ComputeFactory.getAlgorithm("+");
        System.out.println(addAlgorithm.getResult(12.4, 10));
        Algorithm subAlgorithm = ComputeFactory.getAlgorithm("-");
        System.out.println(subAlgorithm.getResult(20, 15));
        Algorithm MulAlgorithm = ComputeFactory.getAlgorithm("*");
        System.out.println(MulAlgorithm.getResult(10, 10));
        Algorithm divisionAlgorithm = ComputeFactory.getAlgorithm("/");
        System.out.println(divisionAlgorithm.getResult(10, 2));

    }
}

security登陆表单

/**
 * @author lzr
 * @date 2020 09 03 20:28
 * @description 登陆表单的配置
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin").password("123").roles("admin")
                .and()
                .withUser("xiaoliu").password("456").roles("user");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/user/**").hasAnyRole("admin", "user")
                .and()
                .formLogin()
                .loginProcessingUrl("/doLogin")//登陆接口
                .loginPage("/login")//跳转到登陆页面的接口
                .successHandler(new AuthenticationSuccessHandler() { //登陆成功处理
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        resp.setContentType("application/json:charset=UTF-8");
                        PrintWriter out = resp.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", 200);
                        map.put("msg", authentication.getPrincipal());
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
                .failureHandler(new AuthenticationFailureHandler() { //登陆失败处理
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8"); //设置json
                        PrintWriter out = resp.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", 401);
                        if (e instanceof LockedException) {
                            map.put("msg", "账户被锁定,登陆失败!");
                        } else if (e instanceof BadCredentialsException) {
                            map.put("msg", "用户名或密码输入错误!");
                        } else if (e instanceof DisabledException) {
                            map.put("msg", "账户被禁用");
                        } else if (e instanceof AccountExpiredException) {
                            map.put("msg", "账户过期,登陆失败!");
                        } else if (e instanceof CredentialsExpiredException) {
                            map.put("msg", "密码过期,登陆失败!");
                        } else {
                            map.put("msg", "登陆失败");
                        }
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        resp.setContentType("application/json;charset=utf-8"); //设置json
                        PrintWriter out = resp.getWriter();
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", 200);
                        map.put("msg", "注销成功!");
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
                .permitAll()
                .and()
                .csrf().disable();
    }
}

9.5 Saturday

方法安全,给单个方法加上安全权限控制。

首先在secrutiyConfig上加注解,开启该功能

@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)

编写service作为测试用例

/**
 * @author lzr
 * @date 2020 09 06 10:15
 * @description
 */
@Service
public class MethodsService {

    @PreAuthorize("hasRole('admin')")
    public String admin(){
        return "hello admin";
    }
    @Secured("ROLE_user")
    public String user(){
        return "hello user";
    }
    @PreAuthorize("hasAnyRole('admin','user')")
    public String hello(){
        return "hello hello";
    }
}

这样访问对应方法必须有相应权限。

9.6 Saturday

创建测试数据库
3个表 user role 和 user-roles关系表

先编写两个实体类
User

**
 * @author lzr
 * @date 2020 09 06 10:50
 * @description
 */
@Data
public class User implements UserDetails { //需实现UserDetails
    private Integer id;
    private String username;
    private String password;
    private boolean enabled;
    private boolean locked;
    private List<Role> roles;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() { //返回所有的角色
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));
        }
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {//是否未过期
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {//是否未锁定
        return !locked;
    }

    @Override
    public boolean isCredentialsNonExpired() {//密码是否未过期
        return true;
    }
}

role

/**
 * @author lzr
 * @date 2020 09 06 10:50
 * @description
 */
@Data
public class Role {
    private Integer id;
    private String name;
    private String nameZh;
}

编写UserService

/**
 * @author lzr
 * @date 2020 09 06 11:34
 * @description
 */
@Service
public class UserService implements UserDetailsService {//实现UserDetailsService
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String usernmae) throws UsernameNotFoundException {//在此验证账户,密码会根据user自动验证
        User user = userMapper.loadUserByUsername(usernmae);
        if (user == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }
        user.setRoles(userMapper.getUserRolesById(user.getId()));//设置角色
        return user;
    }
}

编写UserMapper

/**
 * @author lzr
 * @date 2020 09 06 11:34
 * @description
 */
@Mapper
public interface UserMapper {
    User loadUserByUsername(String usernmae);
    
    List<Role> getUserRolesById(Integer id);
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.maaoooo.security_db_demo.mapper.UserMapper">
    <select id="loadUserByUsername" resultType="com.maaoooo.security_db_demo.entity.User" parameterType="String">
        select * from security.user where username=#{username}
    </select>
    <select id="getUserRolesById" resultType="com.maaoooo.security_db_demo.entity.Role">
        select *  from security.role where id in (select rid from security.user_role where uid=#{id})
    </select>
</mapper>


SecurityConfig

/**
 * @author lzr
 * @date 2020 09 06 11:58
 * @description
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin").hasRole("admin")
                .antMatchers("/dba").hasRole("adb")
                .antMatchers("/user").hasRole("user")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .csrf().disable();
    }

    @Autowired
    private UserService userService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }

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

编写controller测试

/**
 * @author lzr
 * @date 2020 09 06 12:07
 * @description
 */
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(){
        return "hello world!";
    }
    @GetMapping("/adb")
    public String adb(){
        return "adb";
    }
    @GetMapping("/admin")
    public String admin(){
        return "admin";
    }
    @GetMapping("/user")
    public String user(){
        return "user";
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值