码迷,mamicode.com
首页 > 其他好文 > 详细

基于SSM框架的博客系统(二)博主登录功能

时间:2018-03-07 00:50:04      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:pack   info   use   https   aop   servlet   ons   java   idt   

一、        准备

1.数据库

创建表db_blogger:

 1 DROP TABLE IF EXISTS `t_blogger`;
 2 
 3 CREATE TABLE `t_blogger` (
 4 
 5   `id` INT(11) NOT NULL AUTO_INCREMENT,
 6 
 7   `userName` VARCHAR(50) DEFAULT NULL,
 8 
 9   `password` VARCHAR(100) DEFAULT NULL,
10 
11   `profile` TEXT,
12 
13   `nickName` VARCHAR(50) DEFAULT NULL,
14 
15   `sign` VARCHAR(100) DEFAULT NULL,
16 
17   `imageName` VARCHAR(100) DEFAULT NULL,
18 
19   `salt` VARCHAR(100) DEFAULT NULL,
20 
21   PRIMARY KEY (`id`)
22 
23 ) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
24 
25 INSERT  INTO `t_blogger`(`id`,`userName`,`password`,`profile`,`nickName`,`sign`,`imageName`,`salt`) VALUES (1,neya,7f50069012f25a74bb2783a2d7100f0e,NULL,NULL,NULL,NULL,Neya);

 

2.添加shiro支持

 1 <!-- 添加shiro支持 -->
 2 
 3      <dependency>
 4 
 5           <groupId>org.apache.shiro</groupId>
 6 
 7           <artifactId>shiro-core</artifactId>
 8 
 9           <version>1.2.4</version>
10 
11      </dependency>
12 
13     
14 
15      <dependency>
16 
17           <groupId>org.apache.shiro</groupId>
18 
19           <artifactId>shiro-web</artifactId>
20 
21           <version>1.2.4</version>
22 
23      </dependency>
24 
25     
26 
27      <dependency>
28 
29           <groupId>org.apache.shiro</groupId>
30 
31           <artifactId>shiro-spring</artifactId>
32 
33           <version>1.2.4</version>
34 
35      </dependency>

 

二、        登录界面及登录控制

1.     登录界面

在webapp文件夹下创建login.jsp,以上所需文件及图片可由以下链接下载:链接:https://pan.baidu.com/s/1bqCGJld 密码:701g

 

登录界面如下:

           技术分享图片

2.     创建Realm并配置shiro

Shiro是一个Java平台的开源权限框架,用于认证和访问授权。具体来说,满足对如下元素的支持:

1)用户,角色,权限(仅仅是操作权限,数据权限必须与业务需求紧密结合),资源(url)。

2)用户分配角色,角色定义权限。

3)访问授权时支持角色或者权限,并且支持多级的权限定义。

关于shiro更详细的信息,推荐阅读博客:http://jinnianshilongnian.iteye.com/blog/2018398,暂时可以只阅读前几章,足够本项目使用。

       下面简单说一下本项目中所用到的shiro执行流程:前端从login.jsp获取到用户提交的用户名及密码的表单数据提交到后台的controller处理,在controller相应的登录功能模块中将用户名和密码封装到一个token中(UsernamePasswordToken对象)。在shiro中,应用代码直接交互的对象是Subject,也就是说shiro的对外API核心就是Subject,其代表了当前“用户”,这个用户不一定是具体的人,也可以是与当前应用交互的任何东西。Subject会绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager。在controller中,通过一个Subject实例通过login方法将之前创建的token提交,后续会运行到自定义的MyRealm类,在此类中由方法doGetAuthenticationInfo实现具体的验证逻辑,首先需要根据提交的用户名到数据库中进行查询,得到数据库中相应的密码及盐,然后将用户名、密码、盐封装到一个info(SimpleAuthenticationInfo)中,作为方法的返回值返回,接下来的验证由shiro进行处理,主要是对比提交的token和info中的信息,将token中的密码取出与info中取出的盐使用MD5加密(加密算法及次数在shiro配置文件中配置),得到加密后的字符串与info中的密码字符串进行匹配,相同则验证成功,否则抛出异常。

 

创建包com.neya.shiro,并在其中创建MyRealm类:

 1 public class MyRealm extends AuthorizingRealm{
 2 
 3  
 4 
 5      @Override
 6 
 7      protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
 8 
 9  
10 
11           return null;
12 
13      }
14 
15  
16 
17      @Override
18 
19      protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
20 
21           // TODO Auto-generated method stub
22 
23          
24 
25           return null;
26 
27      }
28 
29     
30 
31       public String getName(){
32 
33            return "myRealm";
34 
35       }
36 
37  
38 
39 }

 

 

在resource中创建shiro 配置文件:applicationContext-shiro:

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 
  3 <beans xmlns="http://www.springframework.org/schema/beans"
  4 
  5      xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
  6 
  7      xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  8 
  9      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 10 
 11      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 12 
 13      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
 14 
 15      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
 16 
 17      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
 18 
 19      http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
 20 
 21  
 22 
 23  
 24 
 25  
 26 
 27     <!--securityManage-->
 28 
 29     <!-- 安全管理器 -->
 30 
 31      <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
 32 
 33         <property name="realm" ref="customRealm" />
 34 
 35     </bean>
 36 
 37  
 38 
 39  
 40 
 41      <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
 42 
 43     
 44 
 45     <bean id="customRealm" class="com.ssm.shiro.MyRealm">
 46 
 47    
 48 
 49     <property name="credentialsMatcher">
 50 
 51                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
 52 
 53                     <!-- 加密方式 -->
 54 
 55                     <property name="hashAlgorithmName" value="MD5" />
 56 
 57                     <!-- 加密次数 -->
 58 
 59                     <property name="hashIterations" value="1"/>
 60 
 61                </bean>
 62 
 63           </property>
 64 
 65     </bean>
 66 
 67  
 68 
 69      <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
 70 
 71     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
 72 
 73     <property name="securityManager" ref="securityManager"/>
 74 
 75 </bean>
 76 
 77  
 78 
 79  
 80 
 81 <!--web.xml中shiro的filter对应的bean-->
 82 
 83     <!-- Shiro 的Web过滤器 -->
 84 
 85     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
 86 
 87        <property name="securityManager" ref="securityManager" />  
 88 
 89  <!--        loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
 90 
 91         <property name="loginUrl" value="/blogger/login.do" />
 92 
 93      <!--   认证成功统一跳转到first.do,建议不配置,不配置的话shiro认证成功会自动到上一个请求路径 -->
 94 
 95         <property name="filterChainDefinitions">
 96 
 97             <value>
 98 
 99               
100 
101                 /login=anon
102 
103                     /admin/**=authc
104 
105                    
106 
107                     <!-- -/**=authc 表示所有的url都必须认证通过才可以访问- -->
108 
109               
110 
111                 <!--/**=anon 表示所有的url都可以匿名访问,anon是shiro中一个过滤器的简写,关于shiro中的过滤器介绍见-->
112 
113  
114 
115             </value>
116 
117         </property>
118 
119     </bean>
120 
121  
122 
123 </beans>

 

3.     登录控制

使用上一篇中的逆向工程文件generatorConfig.xml将表t_blogger生成相应的实体类及mapper文件,创建相应的Service及实现类:

BloggerService.java:

1 package com.neya.service;
2 
3 import com.neya.domain.Blogger;
4 
5 public interface BloggerService {
6 
7      public Blogger getBloggerByName(String username);
8 
9 }

 

 

BloggerServiceImpl.java:

 1 package com.neya.service.impl;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 
 5 import org.springframework.stereotype.Service;
 6 
 7 import com.neya.domain.Blogger;
 8 
 9 import com.neya.mapper.BloggerMapper;
10 
11 import com.neya.service.BloggerService;
12 
13  
14 
15 @Service
16 
17 public class BloggerServiceImp implements BloggerService {
18 
19  
20 
21      @Autowired
22 
23      private BloggerMapper bloggerMapper;
24 
25     
26 
27      @Override
28 
29      public Blogger getBloggerByName(String username) {
30 
31           // TODO Auto-generated method stub
32 
33           Blogger blogger=bloggerMapper.getByUserName(username);
34 
35           return blogger;
36 
37      }
38 
39 }

 

由于逆向工程自动创建的mapper中没有getByUserName方法,所以需要在BloggerMapper.java中添加此方法并在BloggerMapper.xml中实现:

1 <select id="getByUserName" parameterType="String" resultMap="ResultMapWithBLOBs">
2 
3           select * from t_blogger where userName=#{userName}
4 
5 </select>

 

在MyRealm的doGetAuthenticationInfo方法中添加如下代码:

 1 String username=(String) token.getPrincipal();
 2 
 3           Blogger blogger=bloggerService.getBloggerByName(username);
 4 
 5           if(blogger!=null){//能查询到数据则将查询到的数据封装到info中与token比较
 6 
 7                SecurityUtils.getSubject().getSession().setAttribute("currentUser", blogger);
 8 
 9                ByteSource credentialsSalt = ByteSource.Util.bytes(blogger.getSalt());
10 
11                AuthenticationInfo info=new SimpleAuthenticationInfo(blogger.getUsername(), blogger.getPassword(),credentialsSalt,getName());
12 
13                return info;
14 
15           }else{
16 
17                return null;
18 
19           }

 

前面的login.jsp中,表单提交的地址为"${pageContext.request.contextPath}/blogger/login.do",所以在controller包中创建相应的BloggerController类并使用@RequestMapping注解映射:

package com.neya.controller;

 

import javax.servlet.http.HttpServletRequest;

 

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.subject.Subject;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

 

import com.neya.domain.Blogger;

import com.neya.service.BloggerService;

 

@Controller

@RequestMapping("/blogger")

public class BloggerController {

    

     @Autowired

     private BloggerService bloggerService;

    

     @RequestMapping("/login")

     public String login(Blogger blogger,HttpServletRequest request){//参数使用spring的自动绑定,从blogger中寻找相应的字段与前端提交的表单的‘name‘匹配,相同则会对blogger的属性直接赋值,比如表单中提交了两项,name属性分别为username和password,则在blogger中,若发现有这两个字段,则直接将提交的数据对这两个字段赋值

          Subject subject=SecurityUtils.getSubject();

          UsernamePasswordToken token=new UsernamePasswordToken(blogger.getUsername(),blogger.getPassword());//根据前端提交的信息创建token

          try{

               subject.login(token);//登录,这里会执行到MyRealm中的代码

               return "redirect:/admin/main.jsp";//登录成功则跳转到相应的后台管理界面

          }catch(Exception e){//验证失败会抛出异常,将失败信息写回前端

               e.printStackTrace();

               request.setAttribute("blogger", blogger);

               request.setAttribute("errorInfo", "用户名或密码错误");

               return "login";

          }

     }

}

 

main.jsp及其所需要的文件在以下链接中:

链接:https://pan.baidu.com/s/1jJ9K8rO 密码:l65t

main.jsp放在webapp下的admin文件夹中

另外,在web.xml中还需要加入shiro过滤器

  

 1  <!--在这里配置shiro的filter-->
 2 
 3    <!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
 4 
 5     <filter>
 6 
 7        <filter-name>shiroFilter</filter-name>
 8 
 9        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
10 
11    <!--     设置true由servlet容器控制filter的生命周期 -->
12 
13        <init-param>
14 
15            <param-name>targetFilterLifecycle</param-name>
16 
17            <param-value>true</param-value>
18 
19        </init-param>
20 
21      <!--   设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean -->
22 
23        <init-param>
24 
25            <param-name>targetBeanName</param-name>
26 
27            <param-value>shiroFilter</param-value>
28 
29        </init-param>
30 
31    </filter>
32 
33    <filter-mapping>
34 
35        <filter-name>shiroFilter</filter-name>
36 
37        <url-pattern>/*</url-pattern>
38 
39    </filter-mapping>

 

接下来启动tomcat,并在浏览器中输入http://localhost:8080/MyBlog/login.jsp,填入用户名neya及密码123456,点击登录即可跳转到相应后台管理界面

基于SSM框架的博客系统(二)博主登录功能

标签:pack   info   use   https   aop   servlet   ons   java   idt   

原文地址:https://www.cnblogs.com/neya/p/8519571.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!