Skip to content

Commit

Permalink
allow you use custom key to authenticate
Browse files Browse the repository at this point in the history
  • Loading branch information
hax0r31337 committed Mar 14, 2022
1 parent b0ef075 commit e5dd0c5
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 23 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Elixir is a library designed to make minecraft login easier.
We have a maven repo for this project.
~~~groovy
repositories {
maven { url = "https://getfdp.today/repo/" }
maven { url = "https://repo.getfdp.today/" }
}
dependencies {
Expand All @@ -29,6 +29,7 @@ me.liuli.elixir.manage.AccountSerializer.accountInstance(
Username: `username`, Password: Empty String

### Mojang Account
**MOJANG REMOVED SUPPORT FOR MOJANG ACCOUNTS! We will remove the API in 1.3.0 or later**
Username: `[email protected]`, Password: `password`

### Microsoft Account
Expand All @@ -53,6 +54,14 @@ val microsoftAccount = MicrosoftAccount.buildFromOpenBrowser(object : MicrosoftA
})
~~~

###Custom Client Keys
You can use your own client keys. You need to create a AuthMethod instance, and add it with a custom id to the registry in AuthMethod Companion object.
~~~kotlin
MicrosoftAccount.AuthMethod("c6cd7b0f-077d-4fcf-ab5c-9659576e38cb", "vI87Q~GkhVHJSLN5WKBbEKbK0TJc9YRDyOYc5", "http://localhost:1919/login", "XboxLive.signin%20offline_access", "d=<access_token>").also {
MicrosoftAccount.AuthMethod.Companion.registry["CUSTOM"] = it
}
~~~

## Json Form
We provide a json form to make data easier to read and write.
~~~kotlin
Expand Down
31 changes: 19 additions & 12 deletions src/main/java/me/liuli/elixir/account/MicrosoftAccount.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ class MicrosoftAccount : MinecraftAccount("Microsoft") {
override fun toRawJson(json: JsonObject) {
json["name"] = name
json["refreshToken"] = refreshToken
json["authMethod"] = authMethod.name
json["authMethod"] = AuthMethod.registry.filterValues { it == authMethod }.keys.firstOrNull() ?: throw LoginException("Unregistered auth method")
}

override fun fromRawJson(json: JsonObject) {
name = json.string("name")!!
refreshToken = json.string("refreshToken")!!
authMethod = AuthMethod.values().find { it.name.equals(json.string("authMethod"), true) } ?: AuthMethod.MICROSOFT
authMethod = AuthMethod.registry[json.string("authMethod")!!] ?: throw LoginException("Unregistered auth method")
}

companion object {
Expand Down Expand Up @@ -102,7 +102,7 @@ class MicrosoftAccount : MinecraftAccount("Microsoft") {
*
* @credit https://github.com/XboxReplay/xboxlive-auth
*/
fun buildFromPassword(username: String, password: String): MicrosoftAccount {
fun buildFromPassword(username: String, password: String, authMethod: AuthMethod = AuthMethod.MICROSOFT): MicrosoftAccount {
fun findArgs(resp: String, arg: String): String {
return if (resp.contains(arg)) {
resp.substring(resp.indexOf("$arg:'") + arg.length + 2).let {
Expand All @@ -113,10 +113,8 @@ class MicrosoftAccount : MinecraftAccount("Microsoft") {
}
}

val method = AuthMethod.MICROSOFT

// first, get the pre-auth url
val preAuthConnection = HttpUtils.make(replaceKeys(method, XBOX_PRE_AUTH_URL), "GET")
val preAuthConnection = HttpUtils.make(replaceKeys(authMethod, XBOX_PRE_AUTH_URL), "GET")
val html = preAuthConnection.inputStream.reader().readText()
val cookies = (preAuthConnection.headerFields["Set-Cookie"] ?: emptyList()).joinToString(";")
val urlPost = findArgs(html, "urlPost")
Expand All @@ -140,14 +138,14 @@ class MicrosoftAccount : MinecraftAccount("Microsoft") {
authConnection.disconnect()

// pass the code to [buildFromAuthCode]
return buildFromAuthCode(code, method)
return buildFromAuthCode(code, authMethod)
}

/**
* Create a new [MicrosoftAccount] from OAuth
*/
fun buildFromOpenBrowser(handler: OAuthHandler): OAuthServer {
return OAuthServer(handler).also { it.start() }
fun buildFromOpenBrowser(handler: OAuthHandler, authMethod: AuthMethod = AuthMethod.AZURE_APP): OAuthServer {
return OAuthServer(handler, authMethod).also { it.start() }
}

fun replaceKeys(method: AuthMethod, string: String)
Expand All @@ -157,9 +155,18 @@ class MicrosoftAccount : MinecraftAccount("Microsoft") {
.replace("<scope>", method.scope)
}

enum class AuthMethod(val clientId: String, val clientSecret: String, val redirectUri: String, val scope: String, val rpsTicketRule: String) {
MICROSOFT("00000000441cc96b", "", "https://login.live.com/oauth20_desktop.srf", "service::user.auth.xboxlive.com::MBI_SSL", "<access_token>"),
AZURE_APP("c6cd7b0f-077d-4fcf-ab5c-9659576e38cb", "vI87Q~GkhVHJSLN5WKBbEKbK0TJc9YRDyOYc5", "http://localhost:1919/login", "XboxLive.signin%20offline_access", "d=<access_token>")
class AuthMethod(val clientId: String, val clientSecret: String, val redirectUri: String, val scope: String, val rpsTicketRule: String) {
companion object {
val registry = mutableMapOf<String, AuthMethod>()

val MICROSOFT = AuthMethod("00000000441cc96b", "", "https://login.live.com/oauth20_desktop.srf", "service::user.auth.xboxlive.com::MBI_SSL", "<access_token>")
val AZURE_APP = AuthMethod("c6cd7b0f-077d-4fcf-ab5c-9659576e38cb", "vI87Q~GkhVHJSLN5WKBbEKbK0TJc9YRDyOYc5", "http://localhost:1919/login", "XboxLive.signin%20offline_access", "d=<access_token>")

init {
registry["MICROSOFT"] = MICROSOFT
registry["AZURE_APP"] = AZURE_APP
}
}
}

interface OAuthHandler {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/me/liuli/elixir/account/MojangAccount.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import me.liuli.elixir.utils.set
import me.liuli.elixir.utils.string
import java.net.Proxy

@Deprecated("Mojang removed support for MojangAccount")
class MojangAccount : MinecraftAccount("Mojang") {
override var name = ""
var password = ""
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/me/liuli/elixir/compat/OAuthServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ import java.net.InetSocketAddress
import java.util.concurrent.Executors
import java.util.concurrent.ThreadPoolExecutor

class OAuthServer(val handler: MicrosoftAccount.OAuthHandler) {
private val httpServer = HttpServer.create(InetSocketAddress("localhost", 1919), 0)
class OAuthServer(val handler: MicrosoftAccount.OAuthHandler,
private val authMethod: MicrosoftAccount.AuthMethod = MicrosoftAccount.AuthMethod.AZURE_APP,
private val httpServer: HttpServer = HttpServer.create(InetSocketAddress("localhost", 1919), 0),
private val context: String = "/login") {
private val threadPoolExecutor = Executors.newFixedThreadPool(10) as ThreadPoolExecutor

/**
* Start the server.
*/
fun start() {
httpServer.createContext("/login", OAuthHttpHandler(this))
httpServer.createContext(context, OAuthHttpHandler(this, authMethod))
httpServer.executor = threadPoolExecutor
httpServer.start()
handler.openUrl(MicrosoftAccount.replaceKeys(MicrosoftAccount.AuthMethod.AZURE_APP, MicrosoftAccount.XBOX_PRE_AUTH_URL))
handler.openUrl(MicrosoftAccount.replaceKeys(authMethod, MicrosoftAccount.XBOX_PRE_AUTH_URL))
}

/**
Expand All @@ -36,12 +38,13 @@ class OAuthServer(val handler: MicrosoftAccount.OAuthHandler) {
/**
* The handler of the OAuth redirect http request.
*/
class OAuthHttpHandler(private val server: OAuthServer) : HttpHandler {
class OAuthHttpHandler(private val server: OAuthServer, private val authMethod: MicrosoftAccount.AuthMethod) : HttpHandler {

override fun handle(exchange: HttpExchange) {
val query = exchange.requestURI.query.split("&").map { it.split("=") }.associate { it[0] to it[1] }
if(query.containsKey("code")) {
try {
server.handler.authResult(MicrosoftAccount.buildFromAuthCode(query["code"]!!, MicrosoftAccount.AuthMethod.AZURE_APP))
server.handler.authResult(MicrosoftAccount.buildFromAuthCode(query["code"]!!, authMethod))
response(exchange, "Login Success", 200)
} catch (e: Exception) {
server.handler.authError(e.toString())
Expand Down
11 changes: 7 additions & 4 deletions src/test/java/me/liuli/elixir/test/ElixirTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import me.liuli.elixir.utils.toJsonString
fun main(args: Array<String>) {
testCracked()
testMojang()
testMicrosoftBrowser()
testMicrosoftDirect()
val custom = MicrosoftAccount.AuthMethod("c6cd7b0f-077d-4fcf-ab5c-9659576e38cb", "vI87Q~GkhVHJSLN5WKBbEKbK0TJc9YRDyOYc5", "http://localhost:1919/login", "XboxLive.signin%20offline_access", "d=<access_token>").also {
MicrosoftAccount.AuthMethod.Companion.registry["CUSTOM"] = it
}
testMicrosoftBrowser(custom)
testMicrosoftDirect() // you can only use microsoft official key to login with direct mode
}

private fun testCracked() {
Expand Down Expand Up @@ -71,7 +74,7 @@ fun testMicrosoftDirect() {
println(AccountSerializer.toJson(microsoftAccount).toJsonString())
}

fun testMicrosoftBrowser() {
fun testMicrosoftBrowser(authMethod: MicrosoftAccount.AuthMethod) {
val microsoftAccount = MicrosoftAccount.buildFromOpenBrowser(object : MicrosoftAccount.OAuthHandler {
override fun openUrl(url: String) {
println("Open url: $url")
Expand All @@ -85,5 +88,5 @@ fun testMicrosoftBrowser() {
override fun authError(error: String) {
println("Auth error: $error")
}
})
}, authMethod)
}

0 comments on commit e5dd0c5

Please sign in to comment.