Java-Security(一):初體驗


Spring Security的前身是Acegi,在被收納為Spring子項目后正式更改名為 Spring Security。本博客基於Spring Security的版本是 5.2.0.RELEASE。

Spring Security 5.2.0.RELEASE 支持原聲的OAuth2框架,支持更現在化的密碼加密方式。

Spring Security支持廣泛的認證技術,這些技術大多由三方或相關標准組織開發。Spring Security已經集成的認證技術支持如下:

  •     HTTP BASIC authentication headers (一個基於IETF RFC的標准)
  •     HTTP Digest authentication headers (一個基於IETF RFC的標准)
  •     HTTP X.509 client certificate exchange (一個基於IETF RFC的標准)
  •     LDAP (一個非常常見的跨平台認證需要做法,特別是在大環境)
  •     Form-based authentication (提供簡單用戶接口的需求)
  •     OpenID authentication(一種去中心化的身份認證方式)
  •     Authentication based on pre-established request headers(基於預先建立的請求頭進行認證):(比如Computer Associates Siteminder,一種用戶身份驗證及授權的集中式安全基礎方案)
  •     JA-SIG Central Authentication Service (也被稱為CAS,這是一個流行的開源單點登錄系統)
  •     Transparent authentication context propagation for Remote Method Invocation (RMI) and HttpInvoker (一個Spring遠程調用協議)
  •     Automatic “remember-me” authentication (這樣你可以設置一段時間,避免在一段時間內還需要重新驗證)
  •     Anonymous authentication (允許未認證的任何調用,自動假設一個特定的安全主體)
  •     Run-as authentication (這在一個會話內使用不同安全身份的時候是非常有用的)
  •     Java Authentication and Authorization Service (JAAS,java驗證和授權API)
  •     Java EE container authentication:允許系統繼續使用容器管理這種身份驗證方式
  •     Kerberos:一種使用對稱秘鑰機制,允許客戶端與服務器相互確認身份和認證協議。

除此之外,Spring Security還引入了一些第三方包,用於支持更多認證技術,比如:JOSSO等。如果這些技術都無法滿足需求,則Spring Security允許我們編程寫自己的認證技術。

因此,在大部分情況下,當我們有java應用安全方面需求時,選擇Spring Security往往是正確的而有效的。

在授權上,Spring Security 不僅支持基於URL對Web的請求授權,還支持方法訪問授權、對象訪問授權等,基本涵蓋了常見的大部分授權場景。

新建Spring Security Maven項目

1)新建spring-security-01 maven 項目

pom.xml如下:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <springframework.version>5.2.0.RELEASE</springframework.version>
    <com.alibaba.version>1.1.21</com.alibaba.version>
    <mysql.version>8.0.11</mysql.version>
    <org.mybatis.version>3.4.6</org.mybatis.version>
    <org.mybatis.spring.version>2.0.3</org.mybatis.spring.version>
    <org.aspectj.version>1.9.4</org.aspectj.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${springframework.version}</version>
    </dependency>

    <!--AOP aspectjweaver 支持 -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>${org.aspectj.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${org.aspectj.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>${springframework.version}</version>
    </dependency>

    <!--訪問RDBMS-MySQL依賴 -->
    <!--MyBatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${org.mybatis.version}</version>
    </dependency>
    <!-- Mybatis自身實現的Spring整合依賴 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${org.mybatis.spring.version}</version>
    </dependency>

    <!--MySql數據庫驅動 -->
    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>${com.alibaba.version}</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.13</version>
    </dependency>

    <!--form 設置為enctype="multipart/form-data",多文件上傳,在applicationContext.xml中配置了bean
            multipartResolver時,需要依賴該包。 -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.6</version>
    </dependency>

    <!-- 編譯依賴 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!--日志支持 -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.26</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.26</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

    <!-- redis依賴包 -->
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.1.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>2.2.3.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
View Code

pom中引入部分包含:spring-framework,springmvc,spring-security,其他。

2)編寫web.xml等配置文件

2.1)web.xml配置

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>

    <welcome-file-list>
        <welcome-file>/index</welcome-file>
    </welcome-file-list>

    <!--加載dao/service/一些共享組件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext-base.xml,
            classpath:applicationContext-security.xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <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>

    <filter>
        <filter-name>multipartFilter</filter-name>
        <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
        <init-param>
            <param-name>multipartResolverBeanName</param-name>
            <param-value>multipartResolver</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>multipartFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
        <init-param>
            <param-name>methodParam</param-name>
            <param-value>_method</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--加載springmvc controller viewsolver 等-->
    <servlet>
        <servlet-name>spring-security-01</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-security-01-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-security-01</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
View Code

web.xml中需要引入filter( characterEncodingFilter 、hiddenHttpMethodFilter 、multipartFilter 、 springSecurityFilterChain):
    2.1.1)characterEncodingFilter:用來實現對請求內容進行encoding處理,防止亂碼;
    2.1.2)hiddenHttpMethodFilter:用來在表單中添加hidden標簽,value=put|delete,實現put、delete方式提交表單;
    2.1.3)multipartFilter:上傳文件過濾器;
    2.1.4)springSecurityFilterChain:加入spring security攔截器,實現認證、授權攔截。

2.2)監聽器ContextLoaderListener

用來初始化spring applicationContext,用來自動掃描dao、service組件,上創解析器組件,以及spring security組件集成;
applicationContext-base.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.dx.test.security"/>

    <!--上傳文件解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"></property>
        <property name="maxUploadSize" value="10240000"></property>
    </bean>
</beans>

applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">
    <!--
    從Spring Security 3.1開始,可以使用多個http元素為不同的請求模式定義單獨的安全過濾器鏈配置。
    -->
    <security:http pattern="/css/**" security="none"/>

    <security:http auto-config="true" use-expressions="false">
        <security:csrf disabled="false"/>
        <security:intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <security:intercept-url pattern="/index" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <security:intercept-url pattern="/**" access="ROLE_USER"/>

        <security:form-login default-target-url="/index" />
        <security:logout delete-cookies="JSESSIONID" logout-success-url="/login" logout-url="/logout" />

    </security:http>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <!-- Password is prefixed with {noop} to indicate to DelegatingPasswordEncoder that
                NoOpPasswordEncoder should be used. This is not safe for production, but makes reading
                in samples easier. Normally passwords should be hashed using BCrypt
                -->
                <security:user name="admin" password="{noop}adminpwd" authorities="ROLE_USER, ROLE_ADMIN"/>
                <security:user name="user" password="{noop}userpwd" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>

</beans>

或者 去掉security:前綴,將<security:http/> 簡寫為<http>的另外一種配置方式:

<?xml version="1.0" encoding="UTF-8"?>
<bean:beans xmlns:bean="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">
    <http pattern="/css/**" security="none"/>

    <http auto-config="true" use-expressions="false">
        <csrf disabled="false"/>
        <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/index" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
        <intercept-url pattern="/**" access="ROLE_USER"/>
        <form-login default-target-url="/index" />
        <logout delete-cookies="JSESSIONID" logout-success-url="/login" logout-url="/logout" />
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="admin" password="{noop}adminpwd" authorities="ROLE_USER, ROLE_ADMIN"/>
                <user name="user" password="{noop}userpwd" authorities="ROLE_USER"/>
            </user-service>
        </authentication-provider>
    </authentication-manager>
</bean:beans>

2.2.1)從Spring Security 3.1開始,可以使用多個http元素為不同的請求模式定義單獨的安全過濾器鏈配置,詳情從上邊配置可見。
2.2.2)form-login是spring security命名空間配置登錄相關信息的標簽,它包含如下屬性:
    1. login-page 自定義登錄頁url,默認為/login
    2. login-processing-url 登錄請求攔截的url,也就是form表單提交時指定的action
    3. default-target-url 默認登錄成功后跳轉的url
    4. always-use-default-target 是否總是使用默認的登錄成功后跳轉url
    5. authentication-failure-url 登錄失敗后跳轉的url
    6. username-parameter 用戶名的請求字段 默認為userName
    7. password-parameter 密碼的請求字段 默認為password
    8. authentication-success-handler-ref 指向一個AuthenticationSuccessHandler用於處理認證成功的請求,不能和default-target-url還有always-use-default-target同時使用
    9. authentication-success-forward-url 用於authentication-failure-handler-ref
    10. authentication-failure-handler-ref 指向一個AuthenticationFailureHandler用於處理失敗的認證請求
    11. authentication-failure-forward-url 用於authentication-failure-handler-ref
    12. authentication-details-source-ref 指向一個AuthenticationDetailsSource,在認證過濾器中使用
2.2.3)密碼的前綴是{noop},以指示DelegatingPasswordEncoder應使用NoOpPasswordEncoder。這對生產是不安全的,但會使在demo中閱讀更容易。通常密碼應該使用BCrypt散列。

2.3)sevlet實現類DispatcherServlet

用來初始化springmvc系統,指定servlet實現類,加載springmvc的controller,view視圖等;
加載文件spring-security-01-servlet.xml中指定了:自動掃描controller包路徑、自動掃描驅動包、開啟aop、jsp視圖解析器。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 開啟controller注解支持 -->
    <context:component-scan base-package="com.dx.test.controller" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan>

    <!-- 使用注解驅動:自動配置處理器映射器與處理器適配器 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!-- 開啟aop,對類代理 -->
    <aop:config proxy-target-class="true"></aop:config>

    <!-- 單獨使用jsp視圖解析器時,可以取消掉注釋,同時注釋掉:下邊的‘配置多個視圖解析’配置-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

 添加views頁面、controller控制類、測試項目

1)添加views頁面和controller類

1)新建view頁面webapp/WEB-INF/views/index.jsp

<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

2)新建LoginController.java

package com.dx.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class LoginController {
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginPage(@RequestParam(value = "error", required = false) String error, Model model) {
        if (error != null) {
            return "login-failure";
        }
        return "login";
    }
}

3)新建IndexController.java

package com.dx.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class IndexController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home() {
        return "redirect:/index";
    }

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index() {
        return "/index";
    }
}

2)啟動項目測試

啟動項目,自動跳轉到http://localhost:8080/spring_security_01_war/下,此時允許訪問,輸入地址:http://localhost:8080/spring_security_01_war/index也是允許訪問的,因為我們再applicationContext-security.xml中配置了'/'和‘/index’是允許任何人訪問的,因此這里可以訪問‘http://localhost:8080/spring_security_01_war/’和‘http://localhost:8080/spring_security_01_war/index’。

訪問'http://localhost:8080/spring_security_01_war/admin',此時會自動跳轉到‘http://localhost:8080/spring_security_01_war/login’登錄頁面。

從頁面查看login頁面html代碼如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Please sign in</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
    <link href="https://getbootstrap.com/docs/4.0/examples/signin/signin.css" rel="stylesheet" crossorigin="anonymous"/>
  </head>
  <body>
     <div class="container">
      <form class="form-signin" method="post" action="/spring_security_01_war/login">
        <h2 class="form-signin-heading">Please sign in</h2>
        <p>
          <label for="username" class="sr-only">Username</label>
          <input type="text" id="username" name="username" class="form-control" placeholder="Username" required autofocus>
        </p>
        <p>
          <label for="password" class="sr-only">Password</label>
          <input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
        </p>
<input name="_csrf" type="hidden" value="a81e8a84-36e7-4594-806b-bb2f43f5013b" />
        <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
      </form>
</div>
</body></html>

備注:

1)上邊頁面是spring-security內部內置攔截未認證時,跳轉的認證頁面。

2)其中配置信息對應的就是applicationContext-security.xml中配置的信息;

3)"_crsf"標簽取決於配置“<security:csrf disabled="false"/>”;如果不想啟用就配置為“<security:csrf disabled="true"/>”,此時頁面中也不會輸出該標簽。

輸入上邊配置的內存賬戶、密碼后,再次訪問/admin就允許訪問。

退出系統
訪問’http://localhost:8080/spring_security_01_war/logout‘,之后會跳轉到’http://localhost:8080/spring_security_01_war/index‘。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM