HTTP基本认证,服务器认证客户端(java-python)
http基本认证    2017-06-23 10:09:39    29    0    0
zejoe   http基本认证

HTTP认证方式:

HTTP请求报头: Authorization

HTTP响应报头: WWW-Authenticate

HTTP认证基于质询 /回应( challenge/response)的认证模式。

基本认证、摘要认证

 

摘要认证原理:(HTTP-Digest)
  1. 客户端发送一个请求,会收到一个401消息,消息中包含一个唯一的字符串:nonce,每次请求都不一样
  2. 客户端将用户名、密码、nonce、HTTP Method和URI为校验值基础进行散列(默认为MD5)的摘要返回给服务器
  3. 服务器根据收到的信息加上存储的密码算出一个新的摘要与请求中的摘要比较,因为每次nonce都会变,就很难做到重放攻击了。

 

基本认证原理:(HTTP-Basic)

  1. 客户端访问一个受http基本认证保护的资源
  2. 服务器返回401状态,要求客户端提供用户名和密码进行认证。(REST 接口在请求时填入用户名密码)
  3. 客户端将输入的用户名密码用Base64进行编码后,采用非加密的明文方式传送给服务器,服务器会生成一个cookie,用于后续传输。
    Authorization: Basic xxxxxxxxxx.
  4. 如果认证成功,则返回相应的资源。如果认证失败,则仍返回401状态,要求重新进行认证。

注意事项:

     以非加密的明文方式传输,虽然转换成了不易被人直接识别的字符串,但是无法防止用户名密码被恶意盗用。安全性不可控,建议与https结合使用
 
java 服务器spring security 实现基本认证:
  1. web.xml中配置spring security过滤器  
    <!--spring Security过滤器,指定请求会经过该过滤器过滤给spring代理-->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>​
  2. 添加spring-security.xml配置文件,并确保web.xml的contextConfigLocation中可以找到该文件
    <context-param>    
        <param-name>contextConfigLocation</param-name>    
        <param-value>classpath:spring-*.xml</param-value>
    </context-param>
       
  3. 在spring-security.xml中作如下配置,自定义配置用户名密码方式
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:security="http://www.springframework.org/schema/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/security
        
        http://www.springframework.org/schema/security/spring-security-4.0.xsd">
        <!--设置认证类型,stateless表示无状态,不使用session-->
        <security:http create-session="stateless">
            <!--pattern="/**"必须为两个*;access属性不加hasXXX()会报500,hasRole()指角色,必须以ROLE_为前缀,hasAnyAuthority()指权限,可以自定义 -->
            <security:intercept-url pattern="/**" access="hasAnyAuthority('ROLE_ADMIN')" />
            <!-- 基础认证-->
            <security:http-basic />
            <!--关闭csrf的跨站点攻击,开启时会引起post请求403-->
            <security:csrf disabled="true" />
        </security:http>
        
        <!--Spring Security开启用户认证-->
        <security:authentication-manager alias="authenticationManager">
            <!-- user-service-ref对应spring中配置的service,表示用户名密码配置方式由用户自定义-->
            <security:authentication-provider user-service-ref="abcService">
            </security:authentication-provider>
            
            <!-- spring代理,用户名密码数据库配置方式,必须有users表和authorities表以及特定表结构
            <security:authentication-provider>
                <security:jdbc-user-service data-source-ref="dataSource" role-prefix="ROLE_"/>
            </security:authentication-provider>
            -->
            
            <!-- spring代理,用户名密码在配置文件配置
            <security:authentication-provider>
                <security:user-service>
                     <security:user name="admin" password="admin123" authorities="ROLE_ADMIN"/>
                 </security:user-service>
            </security:authentication-provider>
            -->
        </security:authentication-manager>
    </beans>​
    
  4. 写一个名为abcService的service,必须要实现spring security的UserDetailsService,且必须返回spring security的UserDetails类    
    @Service("abcService")
    public class ABCUserDetailsService implements IABCUserDetailsService,UserDetailsService {
        private static Logger logger = LogManager.getLogger(ABCUserDetailsService.class);
    
        @Resource
        IUserMetaDao userMetaDao;
        //该方法是spring security验证用户名密码的入口,参数为用户输入的用户名,可以写入自己的实现,返回值为配置的user信息,spring会代理检查用户名密码
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            UserDetails user = userMetaDao.getUserInfoByUsername(username);
            if (user == null) {
                logger.error("** user not found!");
                throw new UsernameNotFoundException("user not found!");
            }
            return user;
        }
    }
  5. 自定义一个user的model,对应配置的用户信息,这里的认证信息从自定义的数据库中读取 
    @Entity(name = "userMeta")
    public class UserMetaEntity implements UserDetails{
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Long id;
        @Column(name = "username", length = 32)
        private String username;
        @Column(name = "password")
        private String password;
        @Column(name = "role", length = 32)
        private String role;
    
        public String getRole() {return role;}
        public void setRole(String role) {this.role = role;}
        public void setUsername(String username) {this.username = username;}
        public void setPassword(String password) {this.password = password;}
        //spring根据这个返回检查用户权限
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            String role = getRole();
            Set<GrantedAuthority> authorities = new HashSet<>();
            authorities.add(new SimpleGrantedAuthority(role));
            return authorities;
        }
        @Override
        public String getPassword() {return this.password;}
        @Override
        public String getUsername() {return this.username;}
        @Override
        public boolean isAccountNonExpired() {return true;}
        @Override
        public boolean isAccountNonLocked() {return true;}
        @Override
        public boolean isCredentialsNonExpired() {return true;}
        @Override
        public boolean isEnabled() {return true;}
    } 

 

python客户端 requests实现基本认证:

  1. 使用requests.Session提交请求,将requests.Session.auth设为元组,存放用户名和密码   
    session=requests.Session()
    session.auth=(user, password)
  2. 原理:requests.Session()底层会检查auth的值,当auth的值为元组且长度为2时,会被认为是基本认证,以基本认证的方式提交请求
 

 

上一篇: J2EE代码混淆

下一篇: tomcat配置https访问实现ssl单向认证

29 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航