首页
网站开发
桌面应用
管理软件
微信开发
App开发
嵌入式软件
工具软件
数据采集与分析
其他
首页
>
> 详细
代做program、代写python/Java程序
项目预算:
开发周期:
发布时间:
要求地区:
Week 13.10-15.10
Preconditions:
Previous assignment completed (instructions assume that you have a basic http server with a capability to receive and
send messages)
Tasks:
- Change your existing http server to https server
- Implement a basic user authentication
Background reading:
- https://en.wikipedia.org/wiki/HTTPS
- https://en.wikipedia.org/wiki/Basic_access_authentication
- https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
- https://docs.oracle.com/en/java/javase/21/docs/api/jdk.httpserver/com/sun/net/httpserver/pack
age-summary.html
Classes needed in the implementation:
- com.sun.net.httpserver.HttpsServer
- com.sun.net.httpserver.HttpsConfigurator
- com.sun.net.httpserver.BasicAuthenticator
- com.sun.net.httpserver.HttpHandler
New tools to learn:
- https://docs.oracle.com/en/java/javase/21/docs//specs/man/keytool.html
Instructions
Step 1 - Create a self-signed certificate
You can create the certificate with following command:
keytool -genkey -alias alias -keyalg RSA -keystore keystore.jks -keysize 2048
Password should be strong but you need to remember as you need it later. The keytool will also ask your name, organization, location information etc. As your first and last name, you must give “localhost” without the quotation marks.
The command creates keystore.jks in to the folder you are currently in. Copy the keystore.jks in to your server project folder.
The keytool is part of the java jdk and if the command cannot be found, you need to either:
- add it to your PATH environment variable so you can use it easily just by writing “keytool”, or
- write the whole path before the “keytool” so it is then found and executed.
Step 2 – Configure server to use TLS/HTTPS
Remember to read the oracle documentation about http server listed in background reading section in first page.
After reading the documentation, simply copy the code just right after the sentence: “A simple example SSLContext could be created as follows:” and paste it to a new function called (such as, you can rename it if you want):
private static SSLContext myServerSSLContext() throws Exception After that, you need to:
- Import the necessary classes to the .java file (shown in errors since they are unknown to IDE before importing them).
- “passphrase” - replace this with the password you gave in Step 1 when you created your self signed certificate.
- “testkeys” - replace this with the key file name you used in the Step 1 — if you followed the instructions, it would be “keystore.jks”.
- As the function should return a SSLContext, do that. You already have the SSLContext object ssl in the code you copied. Return that to the caller
Note that putting password directly to the code is not generally a good idea. There are better ways to provide the passwords but for the coursework this is enough as we are testing our server locally.
Step 3 – Changing HTTP server to HTTPS server
Next, change the HttpServer to HttpsServer (see the difference!) and import that class. You can now remove the HttpServer import since it is no longer needed.
Next thing you need to do is to add code to main() to actually use the function you implemented above. Right after you created the HttpsServer, add this line:
SSLContext sslContext = myServerSSLContext();
So you now call the method you just implemented to create a SSLContext for your HTTPS server, using the self signed certificate you created in the Step 1.
Configure the HttpsServer to use the sslContext by adding this call to setHttpsConfigurator, which you give the sslContext you just created. Add this code right after the line above.
server.setHttpsConfigurator (new HttpsConfigurator(sslContext) { public void configure (HttpsParameters params) {
InetSocketAddress remote = params.getClientAddress(); SSLContext c = getSSLContext();
SSLParameters sslparams = c.getDefaultSSLParameters(); params.setSSLParameters(sslparams);
} });
Step 4 – Error handling
You need to add a try/catch structure to the main function to catch errors that might happen during code execution. You can always just throw the error and let the operating system sort the ending of the problem but that is bad for the person who uses and tries to understand why your program failed. Therefore, we use them to inform what went wrong and possibly log the information to a logger. For now, we just use console print.
If not yet there, add a try catch structure in the main, call all of the code you have there currently in the try block, and in the catch block, print out exception information, for example, just simply:
} catch (Exception e) { e.printStackTrace();
}
You might want to catch different exceptions in different catch blocks to do some more fine grained error handling, for example:
} catch (FileNotFoundException e) {
// Certificate file not found! System.out.println(“Certificate not found!”); e.printStackTrace();
} catch (Exception e) { e.printStackTrace();
}
More advanced logging and error handling will be discussed later during the course.
Step 5 – Test with curl
Note that by default, curl does not accept self signed certificates from a server. So you need to tell curl to accept them. Use an option -k (or longer --insecure). For more information, see https://curl.se/docs/sslcerts.html
Send a HTTPS POST request to the server, use:
UNIX:
curl -k -d 'Kauppatori' https://localhost:8001/info -H 'Content-Type: text/plain’
Or if you are using windows, you might need to replace the ‘ -> “
curl -k -d “Kauppatori” https://localhost:8001/info -H “Content-Type: text/plain”
And receive what you just sent to the server with command: curl -k https://localhost:8001/info
You may use the curl's -trace-ascii out.txt option to see how the client (curl) and the server communicate. Check the generated out.txt -file for details.
Step 6 – basic authentication
The second goal of this exercise is to add Basic HTTP authentication to the server. After this, users cannot POST or GET any messages unless authenticated.
Create new file called UserAuthenticator.java and add a new class to the server project, called UserAuthenticator. It must extend com.sun.net.httpserver.BasicAuthenticator.
We do not yet have a place to store user credentials. It will be implemented in a later exercise. For now, add a member variable Map
to hold the usernames and passwords to the UserAuthenticator. Set it to null when you declare it. You could name the member variable as “users”:
private Map
users = null;
Create a constructor method for the UserAuthenticator class. In the beginning, call super(), BasicAuthenticator’s constructor, giving “info” as the realm to apply the authentication to.
Also, in the constructor, instantiate the “users” map to be a Hashtable
(Map is just an interface class, and Hashtable implements that interface). Then finally, add one dummy user in UserAuthenticator’s constructor to the “users” map:
users = new Hashtable
();
users.put("dummy", "passwd");
Finally, implement the checkCredentials method inherited from the BasicAuthenticator class. There, you should check if, in the Hashmap, there is a username/password that matches the ones in the parameters of checkCredentials. If yes, return true, otherwise return false.
Now you have a simple basis for an authenticator for the server. Later, users can register as users to the server, and the credentials they send are added to the Hashtable. Even later in the course, you will actually store this user information into a database, instead of using a Hashmap.
But where do you call these methods to verify the user? You do not call them directly. Instead, you tell to the context created earlier in the Exercise 1 to use this authenticator when serving client requests.
In the Server’s main method, just before creating the context, create an instance of the UserAuthenticator. You already have the code to create the context by calling server.createContext. Change this so that you take the return value of server.createContext function (we did not care about that earlier) to a HttpContext variable. Then set the authenticator for that context by calling setAuthenticator, giving your UserAuthenticator as a parameter.
Step 7 – Test the authentication
In curl you need to authenticate using the same username and password you created in the UserAuthenticator (assuming user “dummy” and password “passwd”, you may have something different there):
curl -u dummy:passwd -k https://localhost:8001/info
Note the -u (as in user) option and the username and the password given. The same applies obviously to POSTing messages, since the same basic authentication is applied to that realm too.
UNIX:
curl -u dummy:passwd -k -d 'Yliopisto' https://localhost:8001/info -H 'Content-Type: text/plain’ WINDOWS:
curl -u dummy:passwd -k -d “Nallikari” https://localhost:8001/info -H “Content-Type: text/plain”
Step 8 – Functionality for users to register
For registration, create a new HttpHandler with a new realm (or path) “/registration”. This is needed as info -realm expects the user to be authenticated and therefore it cannot accept new users (as they do not have the credentials yet).
Users can then register via this https: /localhost:8001/registration address, since the authentication implemented in Step 6 only applies to the “info” realm. So we are not going to set an authenticator for this new HttpHandler with “registration” realm. What you need to do is:
- Create a new class RegistrationHandler, which (like Server.java if you followed the course example) implements HttpHandler interface.
- Create a constructor for RegistrationHandler, that takes as a parameter a UserAuthenticator object.
- RegistrationHandler also needs to have a UserAuthenticator as a member variable so add it there.
- In the constructor of RegistrationHandler, assign UserAuthenticator to the member variable,
because the RegistrationHandler must be able to use the UserAuthenticator later when handling
POST requests from clients to authenticate users.
- Handle HTTP POST messages from clients, checking content type and content length etc. (see steps
below).
o ButdonothandleHTTPGETinRegistrationHandler!Wedonotwanttoprovideanyuser
information to the clients through this non-authenticated path — the client could be malicious, attempting to fish user information from registered users through this path that is not using authorization! You can respond to HTTP GET requests with error 400 and response body “Not supported”.
- For now, we assume that the clients send the registration information in the HTTP POST request body as a simple string “username:password”. (Later all content between client and the server will be JSON structures).
- Read the HTTP POST request body and parse the content. You can easily separate the two parts of “username:password” using Java String class’ split() method.
- Add the new user to UserAuthenticator from the two strings you got from calling String.split(). Obviously you want to check that the splitted string array has really got two strings, and if not, a
response to client is needed that data was not OK. You need to add a new method to the UserAuthenticator:
public boolean addUser(String userName, String password) { // TODO implement this by adding user to the Hashtable
}
Note: do not allow registering same username twice! This would actually lead to a situation where the existing user’s password is changed to the new one, since the data structure here is a Map. Map can only hold one key value, assigning a new element with a same key effectively just changes the value of the key- value pair -- the password! So check that the key does not exist and only then add the new user to the hash table.
Changing user credentials for an existing user should happen elsewhere (not in this handler) so that user is properly authenticated before allowing changing user data! Remember, users are not authenticated using HTTP Basic authentication when using the / registration URL path!
So if the username is already in the Hashtable, return false to the RegistrationHandler, which should pass the error to the client in the response! You can select which HTTP error code to pass to client, but for example 403, 405 might be good ones. Response body can further clarify to client what went wrong, for example: "User already registered”.
Finally, in the Server’s main function, instantiate the user registration Handler, when creating a new “/registration” Context
Step 9 – Test user registration with curl
You should be able to register new users with curl like this:
UNIX
curl -k -d 'dummyuser2:stillapassword' https://localhost:8001/registration -H 'ContentType: text/plain’ WINDOWS
curl -k -d “dummyuser2:stillapassword” https://localhost:8001/registration -H “ContentType: text/plain”
Note the path “/registration” in the address, and that content to the HTTP POST now has the username and password separated by “:”
Test also sending new locations with the created user.
Step 10 – sending the code to gitlab
After finishing your testing, make sure you replace the keystore location and password with args[0] and args[1] to allow the gitlab pipeline to replace both keystore location and password with server generated one. Your code will not compile if this has not been done (NOTE: in some cases it might actually work due
keystore being part of your commit and the password hardcoded in your code (especially if the keystore location and path is in project root folder), this might work but is unintended and can cause problems in future).
Additional tasks (refactoring code):
- Create a handler -class and move the handler implementation from Server class to it if you haven’t done so. It makes the project and code more clean. (For example HandleLocation -class, HandleRegistrations -class, etc...) Markus edit: unnecessary instructions, the original reference was to refactor the code IF the handle -class was implemented as part of the Server.java class where the main function was also present due examples.
Troubleshooting
keytool is not found.
- As explained in the instructions, find the JDK bin directory where it should be. Add that path to the computers PATH environment variable, or launch the tool with full path to the keytool binary.
When server launches, it cannot find the certificate file.
- If the file is without path, place it in the server root directory and launch the server from command line in that directory using command java -jar target/your-jarfile.jar.
- You can put the certificate file name with full path information, so it is found.
软件开发、广告设计客服
QQ:99515681
邮箱:99515681@qq.com
工作时间:8:00-23:00
微信:codinghelp
热点项目
更多
代做ceng0013 design of a pro...
2024-11-13
代做mech4880 refrigeration a...
2024-11-13
代做mcd1350: media studies a...
2024-11-13
代写fint b338f (autumn 2024)...
2024-11-13
代做engd3000 design of tunab...
2024-11-13
代做n1611 financial economet...
2024-11-13
代做econ 2331: economic and ...
2024-11-13
代做cs770/870 assignment 8代...
2024-11-13
代写amath 481/581 autumn qua...
2024-11-13
代做ccc8013 the process of s...
2024-11-13
代写csit040 – modern comput...
2024-11-13
代写econ 2070: introduc2on t...
2024-11-13
代写cct260, project 2 person...
2024-11-13
热点标签
mktg2509
csci 2600
38170
lng302
csse3010
phas3226
77938
arch1162
engn4536/engn6536
acx5903
comp151101
phl245
cse12
comp9312
stat3016/6016
phas0038
comp2140
6qqmb312
xjco3011
rest0005
ematm0051
5qqmn219
lubs5062m
eee8155
cege0100
eap033
artd1109
mat246
etc3430
ecmm462
mis102
inft6800
ddes9903
comp6521
comp9517
comp3331/9331
comp4337
comp6008
comp9414
bu.231.790.81
man00150m
csb352h
math1041
eengm4100
isys1002
08
6057cem
mktg3504
mthm036
mtrx1701
mth3241
eeee3086
cmp-7038b
cmp-7000a
ints4010
econ2151
infs5710
fins5516
fin3309
fins5510
gsoe9340
math2007
math2036
soee5010
mark3088
infs3605
elec9714
comp2271
ma214
comp2211
infs3604
600426
sit254
acct3091
bbt405
msin0116
com107/com113
mark5826
sit120
comp9021
eco2101
eeen40700
cs253
ece3114
ecmm447
chns3000
math377
itd102
comp9444
comp(2041|9044)
econ0060
econ7230
mgt001371
ecs-323
cs6250
mgdi60012
mdia2012
comm221001
comm5000
ma1008
engl642
econ241
com333
math367
mis201
nbs-7041x
meek16104
econ2003
comm1190
mbas902
comp-1027
dpst1091
comp7315
eppd1033
m06
ee3025
msci231
bb113/bbs1063
fc709
comp3425
comp9417
econ42915
cb9101
math1102e
chme0017
fc307
mkt60104
5522usst
litr1-uc6201.200
ee1102
cosc2803
math39512
omp9727
int2067/int5051
bsb151
mgt253
fc021
babs2202
mis2002s
phya21
18-213
cege0012
mdia1002
math38032
mech5125
07
cisc102
mgx3110
cs240
11175
fin3020s
eco3420
ictten622
comp9727
cpt111
de114102d
mgm320h5s
bafi1019
math21112
efim20036
mn-3503
fins5568
110.807
bcpm000028
info6030
bma0092
bcpm0054
math20212
ce335
cs365
cenv6141
ftec5580
math2010
ec3450
comm1170
ecmt1010
csci-ua.0480-003
econ12-200
ib3960
ectb60h3f
cs247—assignment
tk3163
ics3u
ib3j80
comp20008
comp9334
eppd1063
acct2343
cct109
isys1055/3412
math350-real
math2014
eec180
stat141b
econ2101
msinm014/msing014/msing014b
fit2004
comp643
bu1002
cm2030
联系我们
- QQ: 9951568
© 2021
www.rj363.com
软件定制开发网!