Commit 44ed04a6 authored by Michael Schimpelsberger's avatar Michael Schimpelsberger
Browse files

basic authentication ready

parent ba603bab
......@@ -13,13 +13,21 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="src/main/webapp/WEB-INF/lib/h2-1.4.197.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8
......@@ -7,6 +7,7 @@
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="context-root" value="at.jku.ce"/>
......
......@@ -44,12 +44,8 @@
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.servlet</artifactId>
<version>10.0-b28</version>
</dependency>
<dependency>
<!-- --><dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
......@@ -65,7 +61,7 @@
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
<dependency>
<!-- <dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
......@@ -75,6 +71,11 @@
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
-->
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
......
package university.at.jku.ce.authentication;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import university.at.jku.ce.dao.StudentDao;
import university.at.jku.ce.dao.h2dao.H2StudentDao;
import university.at.jku.ce.model.User;
/**
* This filter verify the access permissions for a user
* based on username and passowrd provided in request
* */
@Provider
public class AuthenticationFilter implements javax.ws.rs.container.ContainerRequestFilter
{
StudentDao dao=new H2StudentDao();
@Context
private ResourceInfo resourceInfo;
private static final String AUTHORIZATION_PROPERTY = "Authorization";
@Override
public void filter(ContainerRequestContext requestContext)
{
Method method = resourceInfo.getResourceMethod();
//Access allowed for all
if( ! method.isAnnotationPresent(PermitAll.class))
{
//Access denied for all
if(method.isAnnotationPresent(DenyAll.class))
{
throw new NotAuthorizedException("");
}
//Get request headers
final MultivaluedMap<String, String> headers = requestContext.getHeaders();
//Fetch authorization header
final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
//If no authorization information present; block access
BasicAuthenticationUtil.AuthInfo authInfo=BasicAuthenticationUtil.authorize(authorization);
String username=authInfo.getUser();
String password=authInfo.getPassword();
//Verify user access
if(method.isAnnotationPresent(RolesAllowed.class))
{
RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value()));
for (String s:rolesSet) {System.out.println(s);}
//Is user valid?
if( ! isUserAllowed(username, password, rolesSet))
{
throw new NotAuthorizedException("");
}
}
}
}
private boolean isUserAllowed(final String username, final String password, final Set<String> rolesSet){
boolean isAllowed = false;
User user=dao.getUser(username);
if(user.getUsername().equals(username) && user.getPassword().equals(password))
{
if(rolesSet.contains(user.getRole()))
{
isAllowed = true;
}
}
return isAllowed;
}
}
\ No newline at end of file
package university.at.jku.ce.authentication;
import java.util.List;
import java.util.StringTokenizer;
import javax.ws.rs.NotAuthorizedException;
import org.glassfish.jersey.internal.util.Base64;
public class BasicAuthenticationUtil {
private static final String AUTHENTICATION_SCHEME = "Basic";
public static AuthInfo authorize(List<String> authorization ) {
if(authorization == null || authorization.isEmpty())
{
throw new NotAuthorizedException("");
}
//Get encoded username and password
final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
//Decode username and password
String usernameAndPassword = new String(Base64.decode(encodedUserPassword.getBytes()));;
//Split username and password tokens
final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
final String username = tokenizer.nextToken();
final String password = tokenizer.nextToken();
//Verifying Username and password
System.out.println(username);
System.out.println(password);
return new AuthInfo(username, password);
}
public static class AuthInfo {
String user;
String password;
public String getUser() {
return user;
}
public String getPassword() {
return password;
}
public AuthInfo(String user, String password) {
super();
this.user = user;
this.password = password;
}
}
}
package university.at.jku.ce.config;
import org.glassfish.jersey.server.ResourceConfig;
import university.at.jku.ce.authentication.AuthenticationFilter;
public class CustomApplication extends ResourceConfig
{
public CustomApplication()
{
packages("university.at.jku.ce.config");
register(AuthenticationFilter.class);
}
}
package university.at.jku.ce.dao;
import java.util.List;
import java.util.Map;
import university.at.jku.ce.model.Student;
import university.at.jku.ce.model.Study;
import university.at.jku.ce.model.User;
public interface StudentDao {
public Student getStudent(int matrNr);
......@@ -24,4 +24,13 @@ public interface StudentDao {
public Study getInscription(int matrNr, int studyId);
public void removeInscription(int matrNr, int studyId);
public User getUser(String username);
public List<User> getAllUsers();
public void addUser(int id, Student student);
public void removeUser(int id);
}
package university.at.jku.ce.dao;
import java.util.List;
import java.util.Map;
import university.at.jku.ce.model.Subject;
......
package university.at.jku.ce.dao.h2dao;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
......@@ -12,7 +11,6 @@ public class DaoParam {
public static final String USER="sa";
public static final String PASSWORD="";
public static final String JDBC_URL="jdbc:h2:"+getDbPath();
public static final String TCP_PORT="9192";
private static String getDbPath() {
......
......@@ -2,23 +2,13 @@ package university.at.jku.ce.dao.h2dao;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.NotFoundException;
import university.at.jku.ce.dao.DBInitializerDao;
import university.at.jku.ce.model.Student;
public class H2DBInitializerDao implements DBInitializerDao {
......@@ -114,6 +104,16 @@ public class H2DBInitializerDao implements DBInitializerDao {
stmt = con.createStatement();
stmt.executeUpdate(sql);
sql="create table user(\r\n" +
"id INTEGER,\r\n" +
"username VARCHAR2(40) Primary Key,\r\n" +
"password VARCHAR2(40) NOT NULL,\r\n" +
"role VARCHAR2(40),\r\n" +
"check role in ('ADMIN','STUDENT'),\r\n" +
"Foreign key (id) references student(matrnr) ON DELETE CASCADE\r\n" +
");";
stmt = con.createStatement();
stmt.executeUpdate(sql);
// STEP 4: Clean-up environment
stmt.close();
con.close();
......@@ -151,7 +151,15 @@ public class H2DBInitializerDao implements DBInitializerDao {
con = DriverManager.getConnection(DaoParam.JDBC_URL, DaoParam.USER, DaoParam.PASSWORD);
// STEP 3: Execute a query
String sql = "DROP TABLE student CASCADE CONSTRAINTS";
String sql = "DROP TABLE user CASCADE CONSTRAINTS";
try {
stmt = con.createStatement();
stmt.executeUpdate(sql);
} catch (Throwable t) {
System.out.println("Table user did not exist");
}
sql = "DROP TABLE student CASCADE CONSTRAINTS";
try {
stmt = con.createStatement();
stmt.executeUpdate(sql);
......@@ -179,6 +187,8 @@ public class H2DBInitializerDao implements DBInitializerDao {
} catch (Throwable t) {
System.out.println("Table inscription did not exist");
}
// STEP 4: Clean-up environment
stmt.close();
......@@ -229,6 +239,9 @@ public class H2DBInitializerDao implements DBInitializerDao {
sql="SELECT * from inscription where rownum<2";
stmt = con.createStatement();
stmt.executeQuery(sql);
sql="SELECT * from user where rownum<2";
stmt = con.createStatement();
stmt.executeQuery(sql);
} catch (SQLException e) {return false;}
// STEP 4: Clean-up environment
......
......@@ -16,6 +16,7 @@ import javax.ws.rs.NotFoundException;
import javax.ws.rs.ext.Provider;
import university.at.jku.ce.model.Student;
import university.at.jku.ce.model.Study;
import university.at.jku.ce.model.User;
public class H2StudentDao implements StudentDao {
......@@ -118,6 +119,7 @@ public class H2StudentDao implements StudentDao {
@Override
public Student addStudent(Student student) {
int nextMatrNr=0;
try {
// STEP 1: Register JDBC driver
Class.forName(DaoParam.DRIVER);
......@@ -129,7 +131,7 @@ public class H2StudentDao implements StudentDao {
stmt = con.createStatement();
String sql = "SELECT max(matrnr) from student";
rs=stmt.executeQuery(sql);
int nextMatrNr=0;
while (rs.next()) {
nextMatrNr=rs.getInt(1);
}
......@@ -142,7 +144,8 @@ public class H2StudentDao implements StudentDao {
prStmt.setString(2, student.getFirstName());
prStmt.setString(3, student.getLastName());
prStmt.executeUpdate();
// STEP 5: Clean-up environment
stmt.close();
prStmt.close();
......@@ -171,6 +174,7 @@ public class H2StudentDao implements StudentDao {
} //end finally try
rs=null;
} //end try
if (nextMatrNr!=0)addUser(nextMatrNr,student);
return student;
}
......@@ -215,6 +219,7 @@ public class H2StudentDao implements StudentDao {
} //end finally try
rs=null;
} //end try
updateUser(student);
return student;
}
......@@ -258,6 +263,7 @@ public class H2StudentDao implements StudentDao {
} //end finally try
rs=null;
} //end try
removeUser(matrNr);
}
@Override
......@@ -447,4 +453,229 @@ public class H2StudentDao implements StudentDao {
rs=null;
} //end try
}
@Override
public User getUser(String username) {
List<User> user=new ArrayList<User>();
try {
// STEP 1: Register JDBC driver
Class.forName(DaoParam.DRIVER);
//STEP 2: Open a connection
con = DriverManager.getConnection(DaoParam.JDBC_URL,DaoParam.USER,DaoParam.PASSWORD);
//STEP 3: Execute a query
String sql = "SELECT id, username, password, role FROM user WHERE username =?";
prStmt = con.prepareStatement(sql);
prStmt.setString(1, username);
rs=prStmt.executeQuery();
while (rs.next()) {
user.add(new User(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getString(4)));
}
// STEP 4: Clean-up environment
prStmt.close();
con.close();
} catch(SQLException se) {
//Handle errors for JDBC
se.printStackTrace();
throw new RuntimeException();
} catch(Exception e) {
//Handle errors for Class.forName
e.printStackTrace();
} finally {
//finally block used to close resources
try{
if(prStmt!=null) prStmt.close();
} catch(SQLException se2) {
} // nothing we can do
try {
if(con!=null) con.close();
} catch(SQLException se){
se.printStackTrace();
} //end finally try
rs=null;
//end try
}
if (user.size()==1) {return user.get(0);}
else {
if (user.size()<1) {throw new NotFoundException();}
else throw new RuntimeException();
}
}
public List<User> getAllUsers(){
List<User> users=new ArrayList<User>();
try {
// STEP 1: Register JDBC driver
Class.forName(DaoParam.DRIVER);
//STEP 2: Open a connection
con = DriverManager.getConnection(DaoParam.JDBC_URL,DaoParam.USER,DaoParam.PASSWORD);
//STEP 3: Execute a query
String sql = "SELECT id, username, password, role FROM user";
prStmt = con.prepareStatement(sql);
rs=prStmt.executeQuery();
while (rs.next()) {
users.add(new User(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getString(4)));
}
// STEP 4: Clean-up environment
prStmt.close();
con.close();
} catch(SQLException se) {
//Handle errors for JDBC
se.printStackTrace();
throw new RuntimeException();
} catch(Exception e) {
//Handle errors for Class.forName
e.printStackTrace();
} finally {
//finally block used to close resources
try{
if(prStmt!=null) prStmt.close();
} catch(SQLException se2) {
} // nothing we can do
try {
if(con!=null) con.close();
} catch(SQLException se){
se.printStackTrace();
} //end finally try
rs=null;
//end try
}
return users;
}
@Override
public void addUser(int id,Student student) {
try {
// STEP 1: Register JDBC driver
Class.forName(DaoParam.DRIVER);
//STEP 2: Open a connection
con = DriverManager.getConnection(DaoParam.JDBC_URL,DaoParam.USER,DaoParam.PASSWORD);
//Step 3: Find next matrnr
//STEP 4: Execute insert
String sql = "INSERT INTO user values(?,?,?,?)";
prStmt = con.prepareStatement(sql);
prStmt.setInt(1, id);
prStmt.setString(2, student.getLastName().toLowerCase());
prStmt.setString(3, student.getLastName().toLowerCase()+"pw");
prStmt.setString(4, "STUDENT");
prStmt.executeUpdate();
// STEP 5: Clean-up environment
stmt.close();
prStmt.close();
con.close();
} catch(SQLException se) {
//Handle errors for JDBC
se.printStackTrace();
throw new RuntimeException();
} catch(Exception e) {
//Handle errors for Class.forName
e.printStackTrace();
} finally {
//finally block used to close resources
try{
if(stmt!=null) stmt.close();
} catch(SQLException se2) {
} // nothing we can do
try{
if(prStmt!=null) prStmt.close();
} catch(SQLException se2) {
} // nothing we can do
try {
if(con!=null) con.close();
} catch(SQLException se){
se.printStackTrace();
} //end finally try
rs=null;
} //end try
}
@Override
public void removeUser(int id) {
try {
// STEP 1: Register JDBC driver
Class.forName(DaoParam.DRIVER);
//STEP 2: Open a connection
con = DriverManager.getConnection(DaoParam.JDBC_URL,DaoParam.USER,DaoParam.PASSWORD);
//STEP 3: Execute delete
String sql = "DELETE FROM user where id=?";
prStmt = con.prepareStatement(sql);
prStmt.setInt(1, id);
prStmt.executeUpdate();
// STEP 5: Clean-up environment
prStmt.close();
con.close();
} catch(SQLException se) {
se.printStackTrace();