`

jee6 学习笔记 11: Secure JSF2 web app with JAAS and JBoss7.1

阅读更多

This article describes how to secure a JSF2 web application with Java Authentication and Authorization Service (JAAS) and JBoss7.1. It uses a "FORM" authentication method. Users and roles are stored in a mysql database. We also want to use JSF2 tags and Primefaces tags as well, not a plain html form.

 

1. Introduction

 

Briefly, JAAS would be provided by the container, ie, JBoss7.1 in our example. In order to handle the login form by our own application code, we need to activate the login process in the login bean, by calling the JAAS login module api. JEE6/Servelet 3.0 provides JAAS api in the HttpServeltRequest object, as follows:

 

request.login(username, password);
request.logout();

 

So, this results in the login backing bean to get the reference of the HttpServletRequest object and call the login(username, password). Here the username and password would be the form parameters user submitted. This is nothing new.

 

 

2. Configurations

 

JAAS is more about configurations. We need to configure a security domain in JBoss7.1 and secure resources(URLs) in web.xml of our web application. We also need to add a jboss-web.xml to hook up our configured security domain in JBoss7.1 to our web application configurations. In the database, we have two tables "user" and "role". The "user" table would hold username and password etc. The "role" table would hold mappings of "username" to the roles we defined for the web application.

 

2.1 Configure a JBoss7.1 secuirty domain

 

This involves adding our security domain to the "standalone.xml " for the standalone server. Open this file and search for "<security-domains>". Under this section, adding our own security domain configuration:

 

<security-domain name="jwSecureTest">
   <authentication>
      <login-module code="Database" flag="required">
           <module-option name="dsJndiName" value="java:/ProJee6DS"/>
           <module-option name="principalsQuery" 
                       value="select password from user where username=?"/>
           <module-option name="rolesQuery" 
                       value="select role, 'Roles' from role where username=?"/>
       </login-module>
   </authentication>
</security-domain>

 

Our secrity domain is going to use datasource  "java:/ProJee6DS"(u have to configure it. same to the datasource web app uses) to authenticate users. The "principalsQuery" would select user password from table "user" and "rolesQuery" would select the roles that the logged in user would have. Once user logged in successfully, these data would be saved in the login context for the user (-; this is my guess.

 

2.2 Database tables configuration

 

So lets add those "user" and "role" tables in database. We have two roles "admin" and "usr".

 

create table user (
  id int, 
  username varchar(20) not null, 
  password varchar(10) not null, 
  email varchar(100)
);

create table role (
  username varchar(20) not null,
  role varchar(10) not null
);

insert into user values (1, 'j2ee', 'j2ee', null);
insert into user values (2, 'jason', 'jason', 'jason@123.com');

insert into role values ('j2ee', 'admin');
insert into role values ('jason', 'usr');

 

 

2.3 Configure our web application web.xml

 

In "web.xml", we have to define the pages/urls to secure. For example, it needs "admin" role to access. We also define the access error page to handle the http "403" error. Note, we need to define it's a Servlet 3.0 web application. Since the JAAS api only available after 3.0

 

Here's the relevant section:

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns="http://java.sun.com/xml/ns/javaee" 
                xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
		xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="ProJee6" version="3.0">

<!-- except for login.jsf, every page requires at lease role "usr", ie, u need to login -->
	<security-constraint>  
		<web-resource-collection>  
	    	<web-resource-name>login protected resources</web-resource-name>  
			<url-pattern>/home.jsf</url-pattern>
	    	<url-pattern>/tst/*</url-pattern>  
	    </web-resource-collection>  
	    <auth-constraint>  
	    	<role-name>usr</role-name> 
                <role-name>admin</role-name>
	    </auth-constraint>  
</security-constraint>

<!-- /student/* only accessible to users with role "admin" -->
 <security-constraint>

     <web-resource-collection>
            <web-resource-name>protected resources</web-resource-name>
            <url-pattern>/student/*</url-pattern>
	    <http-method>GET</http-method>
	    <http-method>POST</http-method>
      </web-resource-collection>
 
      <auth-constraint>
            <!-- restrict role "usr" to access this page 
            <role-name>usr</role-name>
            -->
            <role-name>admin</role-name>
      </auth-constraint>
        
         <!-- uncomment to configure ssl: need to configure https connector.
	 <user-data-constraint>
	     <transport-guarantee>CONFIDENTIAL</transport-guarantee>    
	 </user-data-constraint>
	 -->
</security-constraint>

<!-- define auth method "FORM" and our login page -->
<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.jsf</form-login-page>
        <form-error-page>/login.jsf</form-error-page>
    </form-login-config>
</login-config>

......

<!-- define our http 403 error page -->
<error-page>
    <error-code>403</error-code>
    <location>/noAccess.jsf</location>
</error-page>

 

 

2.4 Adding jboss-web.xml

 

This descriptor is used to hook up the security domain we defined in JBoss "jwSecureTest" to our application. It needs to be packaged into "WEB-INF/jboss-web.xml":

 

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
	<security-domain>java:/jaas/jwSecureTest</security-domain>   
</jboss-web>

 

 

2.5. Implement our login page and its backing bean

 

We dont need to change our login page at all. Here's it anyway:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"> 
    
<h:head>
	<title>login page</title>
</h:head>

<h:body>
  <p:panel header="Login Panel" style="width:50%">
  <h:messages/>
     <h:form>
     <h:panelGrid columns="2">
         <h:outputLabel value="#{msgs.username}: "/> 
         <h:inputText id="nameId" value="#{loginBean.user.username}" 
              required="true" requiredMessage="username is required"/>
   
         <h:outputLabel value="${msgs.password}: "/> 
         <h:inputSecret id="passId" value="#{loginBean.user.password}" 
              required="true" requiredMessage="password is required"/>
   
         <!-- call action bean method login() -->
         <h:panelGroup>
            <h:commandButton type="submit" 
                     value="#{msgs.login}" action="#{loginBean.login}"/>
            
           <p:spacer width="20"/>

            <h:outputText value="are you #{flash.USER.username}?" 
                     rendered="#{not empty flash.USER.username}"/>
         </h:panelGroup>
      </h:panelGrid>
      </h:form>
  </p:panel>
</h:body>
</html>

 

 

But we need to change the backing bean to start the JAAS login process by calling its api:

 

package com.jxee.action;

import java.io.Serializable;
import java.security.Principal;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.jxee.ejb.usr.UserDAO;
import com.jxee.model.User;

/**
 * Backing bean for login.xhtml
 * @ManagedBean used to replace the declaration of the bean in faces-config.xml
 * <br/>you can give it a name, like @ManagedBean("myBean"), otherwise, it defaults
 * to the class name with the first character lower cased, eg, "loginBean". So in this
 * example, it can be accessed in JSF pages like this: #{loginBean.login}
 */
@ManagedBean
@SuppressWarnings("all")
public class LoginBean implements Serializable {
  
  private static final Logger log = Logger.getLogger(LoginBean.class);
  
  // inject EJB UserDAO for accessing database
  // @EJB private UserDAO userDao;  // this is not used when using JAAS
  
  private User user = new User();
  
  public User getUser() { return this.user; }
  public void setUser(User user) { this.user = user; }
  
  /**
   * jaas login
   */
  public String login() {
      ExternalContext cntxt = FacesContext.getCurrentInstance().getExternalContext();
      HttpServletRequest req = (HttpServletRequest) cntxt.getRequest();

      try {
          req.login(this.user.getUsername(), this.user.getPassword());
          log.info(">>> user logged in: " + this.user.getUsername());
          return "/home.jsf";
      }
      catch(Exception e) {
          log.error(String.format("login failed. user: %s, due to: %s ", 
                              this.user.getUsername(),e.getMessage()));
      }
    
      return "/login.jsf";
  }
  
  /**
   * jaas logout
   */
  public String logout() {

     ExternalContext cntxt = FacesContext.getCurrentInstance().getExternalContext();
     HttpServletRequest req = (HttpServletRequest) cntxt.getRequest();
     Principal pp = req.getUserPrincipal();
     String aname = pp.getName();

     try {
        req.logout();
        log.info(">>> user logged out: " + aname);
     }
     catch(Exception e) {
        log.error(String.format("Error logout user %s, due to: %s", 
                              aname, e.getMessage()));
     }

     return "/login.jsf?faces-redirect=true";
  }

  ......

}

 

The http 403 error page "/noAccess.xhtml":

 

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
   				xmlns:h="http://java.sun.com/jsf/html"
      			xmlns:f="http://java.sun.com/jsf/core"
      			xmlns:ui="http://java.sun.com/jsf/facelets"
      			xmlns:p="http://primefaces.org/ui"
   				template="/template/template1.xhtml">

	<ui:define name="title">home</ui:define>
	
	<ui:define name="content">
	    <p:panel header="Access Error" style="width:60%;border:0px">
	        <b>#{msgs.noAccess}</b>
	    </p:panel>
    </ui:define>
</ui:composition>

 

 

With these configurations, onle users with "admin" role can access the pages "/student/*". This include pages "/student/studentSearch.js" and "student/studentDetails.jsf". That is, according to our database data, user "jason" has no access to these pages.

 

Next, i'll take a look at prorgammatic approach of JAAS to secure application components. JEE6 provides annotations to test if calling client is in a role to secure the calling of a method.

 

 

分享到:
评论

相关推荐

    Jetty中文手册

    Jetty and JEE6 Web Profile 配置参考 Jetty XML语法(Syntax)–Jetty IOC Configuration Jetty XML用法–Using and Combining Jetty Configurations 配置文件 jetty.xml–Server configuration jetty-web.xml–Web...

    JEE_-_Middleware_TP:Java EE和中间件实践活动

    6. **安全机制**:学习如何在Java EE应用中实现身份验证和授权,如JAAS(Java Authentication and Authorization Service)。 7. **微服务架构**:可能涉及将大型Java EE应用拆分为更小、独立的微服务,每个服务都...

    liferayPortal

    - WSRP (full support for 1.0 and 2.0):Web Services for Remote Portlets规范的支持。 - WebDAV:一种基于HTTP的协议,用于用户编辑和管理存储在远端的文件。 #### 十一、其他功能模块 除了上述提到的功能之外,...

    实训商业源码-智能设备-论文模板.zip

    实训商业源码-智能设备-论文模板.zip

    实训商业源码-智慧农场小程序 1.8.8+众筹1.1.0+拼团1.0.0+报名1.0.6-论文模板.zip

    实训商业源码-智慧农场小程序 1.8.8+众筹1.1.0+拼团1.0.0+报名1.0.6-论文模板.zip

    电力电子领域PCS储能变流器双向Buck Boost电池充放电Matlab仿真研究 PI控制 基于文献复现的双向Buck Boost储能变流器的Matlab仿真模型与电压电流双闭环PI控制分析

    内容概要:本文详细探讨了基于文献复现的PCS储能变流器双向Buck Boost电池充放电过程的Matlab仿真模型。首先介绍了PCS储能变流器的重要性和双向Buck Boost技术的应用背景,特别是在可再生能源快速发展的背景下,储能系统的作用愈发关键。接着,文章描述了模型的具体构建方法,包括电池模型、PCS储能变流器模型和母线电压模型,并采用了电压电流双闭环PI控制策略。仿真过程分为三个阶段:0-0.1秒不充不放,0.1-0.3秒充电功率10KW,0.3-0.5秒放电功率15KW。重点讨论了LCL滤波器的效果及其对系统稳定性的影响。最后,提供了简单的Matlab代码片段用于设置仿真参数并运行模型。 适合人群:电力电子领域的研究人员和技术人员,尤其是对储能系统和PCS储能变流器感兴趣的读者。 使用场景及目标:适用于希望深入了解PCS储能变流器双向Buck Boost技术原理的研究人员,以及需要进行储能系统设计和优化的实际工程技术人员。目标是帮助他们掌握该技术的应用,提升系统性能和稳定性。 其他说明:文中提到的相关文献可以提供更多关于LCL滤波器和其他相关技术的详细信息,有助于进一步深入研究。

    实训商业源码-智慧乡村社区V6.3.9+手机录入V1.0.1-论文模板.zip

    实训商业源码-智慧乡村社区V6.3.9+手机录入V1.0.1-论文模板.zip

    减速电机测试上位机软件

    用于生产电机测试的上位机软件,有一定参考价值

    毕业设计-图片格式转换-整站商业源码.zip

    毕业设计-图片格式转换-整站商业源码.zip

    [YOLO11+UADETRAC]UADETRAC车辆识别数据集,使用YOLO11格式进行标注(三)

    车辆识别数据集,使用YOLO11格式进行标注,可以直接进行训练,本数据集包含MVI_40171到MVI_40204及其YOLO标注 0:car 1:van 2:bus 3:others

    电力电子领域中正负序PLL锁相环算法在华为与阳光电源DSP芯片中的应用及C语言实现 DSP芯片

    内容概要:本文详细介绍了华为与阳光电源在电力电子领域中采用的正负序PLL锁相环算法,用于提取和抑制不平衡电压。文章首先解释了正负序PLL锁相环的基本原理,即通过精确控制电源输出的相位来实现对负载电压的稳定控制。接着,文中探讨了该算法的具体应用场景,如高效电源设备的运行和电力系统监控,展示了其在提高设备运行效率和稳定性方面的重要作用。最后,文章讨论了技术细节和实现方式,强调了硬件资源利用效率、数字信号处理技术的应用以及多种滤波技术的使用,确保算法的高精度和稳定性。 适合人群:从事电力电子技术研发的专业人士,尤其是对锁相环算法感兴趣的工程师和技术研究人员。 使用场景及目标:适用于希望深入了解正负序PLL锁相环算法在实际应用中的实现方法和技术细节的人群。目标是帮助读者掌握该算法的工作原理及其在提升电力设备性能方面的应用。 其他说明:文章不仅提供了理论知识,还包括了具体的C语言实现指南,便于读者在实践中理解和应用。

    STM32HAl库驱动8个LED的Proteus仿真及源代码 STM32F103CubeMX生成原代码

    源代码是HAL库 Proteus仿真STM32F103C8芯片

    基于电压外环PI与内环滑膜控制的Buck变换器20V转10V仿真及参数设计 PI控制

    内容概要:本文详细介绍了基于电压外环PI控制和内环滑膜控制的Buck变换器的设计与仿真方法,特别针对将输入电压20V转换为输出电压10V的应用进行了深入探讨。文中首先阐述了PI控制器参数的选择依据及其计算方式,接着重点讲解了滑膜控制的具体实现步骤,包括滑模面的选择、切换函数的设计以及滞环的引入。此外,还提供了MATLAB/Simulink仿真实现的关键代码片段,并分享了一些实用的经验技巧,如在负载突变情况下的优化措施和参数调整策略。最后,作者推荐了几本相关领域的权威参考资料,强调了实际应用中需要注意的安全保护措施。 适合人群:对电力电子技术感兴趣的工程师和技术爱好者,尤其是希望深入了解Buck变换器双环控制系统设计与仿真的专业人士。 使用场景及目标:适用于从事电源管理芯片设计、电力电子设备开发等领域的工作人士,旨在帮助他们掌握先进的Buck变换器控制算法,提高系统的稳定性和响应速度。 其他说明:文中提供的仿真文件已上传至GitHub平台,方便读者下载并进行实验验证。同时提醒读者关注实际工程应用中的安全防护措施,确保电路运行可靠。

    电源设计领域Buck DCDC降压变换器PWM PFM双模式调制电路设计及应用 SPICE

    内容概要:本文详细介绍了基于PWM和PFM双模式调制的Buck DCDC降压变换器的设计方法及其应用场景。文中不仅涵盖了电路的基本架构,还深入探讨了各个子模块如带隙基准、自适应导通时间控制器、比较器、运放、非交叠时钟以及驱动电路的具体实现方式和技术细节。此外,文章提供了完整的电路文件、参考文献、设计文档、仿真报告,并配有部分视频讲解,帮助读者全面理解整个设计流程。特别强调了该设计在不同负载条件下的高效性能表现,尤其是在轻载条件下PFM模式的应用,确保了系统的高效率和平滑模式切换。 适用人群:适用于电源设计领域的初学者和有一定经验的研发人员,尤其是对Buck DCDC降压变换器感兴趣的工程师。 使用场景及目标:本设计旨在为电源管理芯片开发者提供一种高效的降压变换解决方案,特别是在便携式电子设备和其他低功耗系统中。通过学习本文提供的设计方案,读者可以掌握如何优化电路性能,提高响应速度,降低功耗,同时实现无缝模式切换。 其他说明:文章中提到的技术细节对于理解和改进现有电源管理系统非常有价值,尤其是一些创新性的设计思路,如自适应导通时间控制、动态迟滞技术和非交叠时钟生成电路等。

    基于vue+javaScript+css开发的熟食订货系统+源码+文档(毕业设计&课程设计&项目开发)

    基于vue+javaScript+css开发的熟食订货系统+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于vue+javaScript+css开发的熟食订货系统+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于vue+javaScript+css开发的熟食订货系统+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于vue+javaScript+css开发的熟食订货系统+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于vue+javaScript+css开发的熟食订货系统+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于vue+javaScript+css开发的熟食订货系统+源码+文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档

    基于Python的心电图实时监测与处理系统:低通滤波器应用及ECG图像保存

    内容概要:本文介绍了一种利用Python开发的实时心电图(ECG)监测系统。该系统能够实时显示ECG信号,允许用户调整低通滤波器参数,并支持保存采集到的ECG图片。文中详细讲解了系统的各个组成部分及其具体实现方法,包括数据采集、数据处理(如低通滤波)、界面显示以及图片保存等功能。作者还提供了完整的代码示例,展示了如何使用numpy进行数值运算,matplotlib进行图形化展示,scipy进行信号处理。 适合人群:对生物医学工程、医疗健康领域感兴趣的开发者和技术爱好者,尤其是那些想要了解或学习如何使用Python构建简单但实用的医疗设备仿真程序的人群。 使用场景及目标:适用于需要快速搭建原型或进行教学演示的情境下,帮助研究人员更好地理解和研究心脏活动特征。同时,对于初学者来说,这也是一个很好的练习项目,有助于掌握Python编程技巧以及相关库的应用。 其他说明:尽管这是一个简化的版本,但它涵盖了从理论到实践的关键步骤,为后续深入探索打下了坚实的基础。此外,文中提到的所有代码都可以直接运行,便于读者动手尝试。

    基于MATLAB的单闭环直流调速系统设计与仿真:涵盖设计报告、电气接线图及系统要求 电流截止保护

    内容概要:本文详细介绍了基于MATLAB的单闭环直流调速系统的完整设计流程。首先,文中明确了设计要求,包括平滑的速度调节、较宽的调速范围以及稳定的系统性能。接着,作者展示了如何搭建电机模型并选择了PI调节器作为转速调节器,同时提供了具体的参数计算方法。此外,还讨论了动态校正策略,强调了开环频率特性的分析及其对系统稳定性的影响。电流截止保护环节的设计也被提及,确保系统在负载变化时能够保持稳定。最后,通过仿真验证了系统的性能,确保其符合预期的各项指标,并分享了一些实际操作中的经验教训。 适合人群:从事电力电子、自动化控制领域的工程师和技术人员,尤其是那些希望深入了解直流调速系统设计的人群。 使用场景及目标:适用于需要设计高效可靠的直流调速系统的项目,旨在帮助读者掌握从理论到实践的全过程,提高系统设计能力。 其他说明:文中不仅提供了详细的理论推导和公式解释,还有丰富的实战经验和技巧分享,有助于读者更好地理解和应用相关知识。

    【Python编程基础】模块与面向对象编程详解:从入门到实践的全面解析介绍了Python编程中的

    内容概要:本文详细介绍了Python编程中的模块和面向对象思想。首先,阐述了Python在当今编程领域的广泛应用,包括人工智能、数据分析和网络爬虫等。接着,文章深入讲解了Python模块的概念,包括模块的作用、常见的内置模块(如math模块)及其导入方式(import、from...import、from...import *),以及如何创建自定义模块和包。随后,文章探讨了面向对象编程思想的诞生背景及其基本概念,包括对象、类、属性和方法,并重点介绍了面向对象的三大特征:封装、继承和多态。最后,文章通过一个学生管理系统的案例,展示了模块与面向对象思想在实际项目中的结合应用。 适合人群:对Python编程感兴趣的初学者,以及希望深入了解模块和面向对象编程的中级开发者。 使用场景及目标:①理解Python模块的使用方法,包括导入方式和自定义模块的创建;②掌握面向对象编程的基本概念和特性,如类、对象、封装、继承和多态;③学会将模块与面向对象思想结合应用于实际项目开发,提高代码的可维护性和复用性。 阅读建议:本文内容详实,涵盖模块和面向对象编程的基础理论与实践案例。读者应结合实际编程练习,逐步掌握模块的使用技巧和面向对象编程的核心思想。特别是通过案例分析部分,读者可以更好地理解如何将理论应用于实际项目中,提升编程能力。

    微电网控制中改进下垂控制策略及其应用——负载稳压与混合储能系统仿真研究

    内容概要:本文探讨了微电网控制中改进下垂控制策略的应用,旨在解决纯阻性负载和冲击负载对母线电压稳定性的挑战。文中介绍了系统的基础参数,包括电池、超容、光伏等设备的具体配置,并通过Simulink仿真环境建立了双闭环控制、传统下垂控制和改进下垂控制三种模型进行对比。改进下垂控制策略通过引入SOC参数优化了储能系统的性能,减少了直流母线电压的偏差。此外,在改进下垂控制基础上加入了二次控制,提高了系统的响应速度和稳定性。最终,通过对不同负载情况下三种控制方法的表现进行实验和数据分析,验证了改进下垂控制的有效性和优越性。 适合人群:从事电力电子、微电网控制、储能系统等相关领域的研究人员和技术人员。 使用场景及目标:适用于微电网系统的设计与优化,特别是涉及负载稳压和平抑新能源发电功率波动的场合。目标是提升系统的稳定性和效率,确保母线电压在各种负载条件下保持稳定。 其他说明:本文不仅提供了详细的理论分析,还附有完整的仿真模型和参考文档,便于读者理解和复现实验结果。

Global site tag (gtag.js) - Google Analytics