springBoot research (2) - строительные леса

Java задняя часть Spring Shiro

Это было более месяца без обновления этой серии статей. Цель этой проблемы состоит в том, чтобы завершить основные леса.

Дополнительный

Репозиторий github этого проекта:GitHub.com/PC859107393…

Внутреннее облачное хранилище кода этого проекта:git.OSCHINA.net/859107393/M…

Эта серия представляет собой серию статей. Конечно, если у вас нет пружинной основы, я предлагаю вам сначала взглянутьМое практическое руководство по Java

КонечноДоступ к моей короткой книге стал быстрее

Учащиеся, заинтересованные в общении со springboot для быстрой разработки, могут добавить следующую группу пингвинов.

行走的java全栈
Прогулка по полному стеку Java

текст начинается

Сначала нам нужно кратко рассмотреть поддержку, в которой нуждается наш проект:

  • Быстрое развертывание: spring-boot-devtools
  • Связанные с базой данных:

    • Mybatis
    • Mybatis-plus (обычная хрень, встроенный пейджинг)
    • Druid
    • ссылка на базу данных
  • Основная зависимость: весна

  • веб-обработка: springMvc
  • Разрешения и аутентификация: Широ
  • Сетевое сообщение: OKHTTP
  • Разбор JSON: gson, fastJson
  • Документы API в Интернете: SpringFox
  • Движок шаблона: freemarker
  • так далее···

Конечно, просто иметь их недостаточно для завершения строительства проекта, но это краеугольные камни нашего строительства. Заставляет нас развиваться быстрее.

Как собрать базовый проект, мы уже говорили об этом в прошлом выпуске.В этом выпуске мы доделаем базовый каркас проекта.При этом у нас должно быть и базовое строительное мышление проекта.

1. Как завершить вход в систему проверки безопасности

Собственно, это обсуждалось и доделывалось в проекте прошлого сезона, а в этом сезоне как раз говорят о старом. Даже говоря, вход в систему — это простой процесс, но это непростая вещь.

Сначала мы должны сделать:Надежный, безопасный и эффективный. В деталях это: шифрование процесса передачи, шифрование хранения данных, хранилище информационного сервера и простое внешнее отображение. Тогда наши обычные методы обработки:

  • Пароль для входа зашифрован перед передачей
  • тест на стойкость зашифрованного текста
  • Информация о пользователе кэшируется в сеансе

Конкретный код выглядит следующим образом:

@Controller
@Api(description = "外层信息,无需Shiro接管,集成文件下载控制器")
public class MainController{

    @PostMapping(value = "/login", produces = MediaType.TEXT_HTML_VALUE)
    @ApiOperation(value = "/login", notes = "登录后台系统")
    public String login(@ApiParam(hidden = true) ModelMap map,
                        @ApiParam(hidden = true) ShiroHttpServletRequest request,
                        @ApiParam(value = "用户名不能为空,否则不允许登录"
                                , required = true) @RequestParam(value = "userLogin", required = false) String userLogin,
                        @ApiParam(value = "用户密码不能为空且必须为16位小写MD5,否则不允许登录"
                                , required = true) @RequestParam(value = "userPass", required = false) String userPass) {
        User result = null;
        try {
            //1.得到Subject
            Subject subject = SecurityUtils.getSubject();
            //2.调用登录方法
            UsernamePasswordToken token = new UsernamePasswordToken(userLogin, userPass);
            subject.login(token);//当这一代码执行时,就会自动跳入到AuthRealm中认证方法
            result = (User) subject.getPrincipal();
            subject.getSession().setAttribute("userInfo", result);
            return "redirect:/endSys/index";
        } catch (Exception e) {
            e.printStackTrace();
            LogE.getInstance(this.getClass()).logOutLittle(e.getMessage());
            map.addAttribute("msg", e.getMessage());
            return "login";
        }

    }

    @GetMapping(path = "logOut", produces = MediaType.TEXT_HTML_VALUE)
    @ApiOperation(value = "退出登录", notes = "退出登录,清空session")
    public String logOut() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            subject.getSession().removeAttribute("userInfo");
            subject.logout(); // session 会销毁,在SessionListener监听session销毁,清理权限缓存
        }
        return "redirect:/";
    }
}

public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserServiceImpl userService;

    /*
     * 登录信息和用户验证信息验证(non-Javadoc)
     * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken user = (UsernamePasswordToken) token;
        LogE.getInstance(ShiroRealm.class).logOutLittle("开始登录====>\n用户为:" + user.getUsername());

        String userLogin = user.getUsername();
        char[] password = user.getPassword();

        User loginResult = null;
        try {
            loginResult = userService.login(userLogin, new String(password));
        } catch (Exception e) {
            e.printStackTrace();
            LogE.getInstance(ShiroRealm.class).logOutLittle("登录异常结束====>\n用户为:" + user.getUsername());
            throw new AuthenticationException(e.getMessage());
        }
        LogE.getInstance(ShiroRealm.class).logOutLittle("登录成功====>\n用户为:" + user.getUsername());
        return new SimpleAuthenticationInfo(loginResult, user.getPassword(), this.getName());
    }
}

public class MyCredentialsMatcher extends SimpleCredentialsMatcher {

    /**
     * 密码比较方法,有自己的登录校验方法,故此绕过校验
     *
     * @param token
     * @param info
     * @return
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

        return true;
    }
}

Конечно, другой код не такой уж и основной, мы в основном объясняем наш логин вокруг Широ.

Почему бы Широ не взять наши адреса для входа и выхода? Потому что независимо от того, есть ли пользователь или нет при входе или выходе, мы будем выполнять соответствующие операции для сохранения информации о пользователе или очистки информации о пользователе соответственно.

Но только это может завершить проверку входа? неправильно! неправильно! неправильно! Нам нужно перевести страницы, захваченные Широ, в область управления. Также будут весенние настройки, о которых мы говорили в прошлом сезоне. Но в прошлом сезоне была конфигурация XML, на этот раз мы используем конфигурацию Java.


@Configuration
public class ShiroConfig {

    @Bean
    public ShiroRealm realm() {
        ShiroRealm myShiroRealm = new ShiroRealm();
        MyCredentialsMatcher matcher = new MyCredentialsMatcher();
        myShiroRealm.setCredentialsMatcher(matcher); //设置解密规则
        return myShiroRealm;
    }


    //SecurityManager 是 Shiro 架构的核心,通过它来链接Realm和用户(文档中称之为Subject.)
    @Bean
    public DefaultSecurityManager securityManager() {
        DefaultSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm()); //将Realm注入到SecurityManager中。

        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setGlobalSessionTimeout(1800000);   //默认三十分钟

//        Cookie cookie = new SimpleCookie();     //设置cookie
//        cookie.setName("sid");  //java默认值是JSESSIONID
//        cookie.setDomain("acheng1314.cn");  //cookie作用域
//        cookie.setMaxAge(1800); //cookie超时时间30分钟
//        cookie.setHttpOnly(true);
//
//        sessionManager.setSessionIdCookie(cookie);
//        sessionManager.setSessionIdCookieEnabled(true);

        //session会话验证
//        ExecutorServiceSessionValidationScheduler sessionValidationScheduler = new ExecutorServiceSessionValidationScheduler();
//        sessionValidationScheduler.setInterval(3600000);
//        sessionValidationScheduler.setSessionManager(sessionManager);
//
//        sessionManager.setSessionValidationScheduler(sessionValidationScheduler);
//        sessionManager.setSessionValidationSchedulerEnabled(true);

        securityManager.setSessionManager(sessionManager);    //此处已经自动持有DefaultWebSessionManager

        return securityManager;
    }

    //在这里配置url访问规则
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultSecurityManager securityManager) {

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/favicon.ico", "anon");
        filterChainDefinitionMap.put("/static/*/**", "anon");

        //authc表示需要验证身份才能访问,还有一些比如anon表示不需要验证身份就能访问等。
        filterChainDefinitionMap.put("/druid/*/**", "authc");
        filterChainDefinitionMap.put("/endSys/*/**", "authc");
        filterChainDefinitionMap.put("/swagger-ui.html/*/**", "authc");


        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setSuccessUrl("/endSys/index");
//        shiroFilterFactoryBean.setUnauthorizedUrl("/403"); //这里设置403并不会起作用,参考http://www.jianshu.com/p/e03f5b54838c

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

}

Сначала мы сообщаем фреймворку Spring, что это настройка нашего фреймворка и его нужно загрузить. Затем настройте соответствующие компоненты (ShiroRealm, DefaultSecurityManager, ShiroFilterFactoryBean) в этом параметре для реализации соответствующих правил планирования.

Для получения некоторых конкретных сведений, таких как: страница входа в систему, операции с базой данных и т. д., см.код репозитория на гитхабеили посетитьОблако кода

Пока что мы можем войти на домашнюю страницу системы:http://localhost:8181/login

После успешного входа простая домашняя страница выглядит следующим образом:

登录成功后的
После успешного входа

Позвольте мне сказать вам спокойно, моя внутренняя домашняя страница использует ZDRAG для управления внутренней формой веб-страницы.

Конечно, здесь все еще есть небольшая проблема, то есть после истечения срока нашей пользовательской информации мы нажимаем в меню, чтобы сгенерировать внутреннюю форму, чтобы войти в систему (щелкнуть меню после успешного входа в систему, чтобы вернуться к правильному интерфейсу). Мы можем Решите эту небольшую проблему, добавив метод JS.

Суммировать

В этом выпуске в основном обсуждается, что нужно рукам и ногам.

  • Базовые зависимости проекта
  • более безопасный вход

следующее уведомление

Следующая цель — сгенерировать генератор кода и дерево меню.


Если вы признаете, что я сделал, и считаете, что то, что я сделал, полезно для вас, я надеюсь, что вы также можете вознаградить меня чашкой кофе, спасибо.

支付宝捐赠
Alipay пожертвование